AND in RISC-V (RARS) doesn't give me "out of bound" error - bit-manipulation

I'm new to RISC-V and I was making some exercises, I have to take the bits in 3rd and 4th position in x5 register and substitute them to the bits in 7th and 8th position in x6 register. That's what I did (my Professor did it too but i tried to make it different):
.globl _start
.data
.text
_start:
li x5,0x0
li x6,0X33333333333
#take the value from 3rd 4th
andi x7,x5,12
#shift them in 7th 8th
slli x7,x7,4
#set 0 bits in 7th 8th position of x6
andi x6, x6, 0xffffffffffffff3f
#I set the bits I want (in x7) inside x6 using OR
or x6,x6,x7
(I didn't know where to write the code so I just wrote it inside HTML section, hope it's fine)
My problem is: why the last andi works (the one with 0xffffff...)? Shouldn't it give me an "out of bound" error? The immediate field in "and" has only 12 bits.

Related

Incorrect CRC32 output unless input bytes are equal

I need to reproduce the output of a hardware CRC calculator for testing purposes. It is set up for ethernet CRC 32, in trace32 format:
/CRC 32. 0x04C11DB7 1 1 0FFFFFFFF 0FFFFFFFF (checksum width, polynom, input reflection, output reflection, crc init, final XOR)
If I feed it values where the 4 bytes are equal (e.g 0x12121212 as each byte being 0x12), the output will match what I calculate using CRC32 or python.
However if I feed it any value where the 4 bytes are not equal, the results are off. For example 0x12341234 will return 0x093c454b (should be 0xa1768922).
Or 0x12345678 will return 0xAF6D87D2 (should be 0x4a090e98).
In the HW I can only select the init value and the polynomial, beyond feeding it 4 bytes to calculate. Rolling calculations(multiple words worth) behave the same way, the output is correct as long as each word fed to it has all bytes the same. Anything else, the output is off.
I am not too knowledgeable about CRC32 and has run out of ideas. Any pointers would be appreciated, what am I doing wrong here? I have double checked the polynomial, but if that was wrong, I could only get the right results extremely rarely, right?
Thank you!
You get your "should be" with the correct byte order. You get your "will return" by reversing the bytes. The bytes 12 34 56 78 gives, for the CRC you described, 0x4a090e98. The bytes 78 56 34 12 gives the CRC 0xaf6d87d2.
Your question is very vague, with no code or how it is being used. I can only guess that you are giving your CRC routine a 32-bit value instead of bytes, and it is being processed in little-endian order when you are expecting big-endian order.

What does this syntax mean in fortran?

I am working on a project and as I have not coded with Fortran before, I am struggling a lot. My professor gave me a code file which I need to fix but I don't understand the syntax.
So, in the file he has
g = some formula,
1 some formula
2 * some formula
3 / some formula.
What does 1, 2, 3, * and / do?
I asked my Professor, and he said that this is Fortran 77 code and 1, 2, 3 are used as indexing in column 6 and the g is in column 7 as that's how the Fortran code is written. But I was very confused why Fortran 77 only accepts code after column 7?
Thank you for all the replies.
What you are most likely looking at is Fixed source-form statement continuation which is part of the Fixed source form.
Fixed-form formatting is an old way of formatting code which still stems from the old punched-cards. Lines could only be 72 characters long, but sometimes you needed more. Hence, the statement-continuation character:
Except within commentary, character position 6 is used to indicate continuation. If character position 6 contains a blank or zero, the line is the initial line of a new statement, which begins in character position 7. If character position 6 contains any character other than blank or zero, character positions 7–72 of the line constitute a continuation of the preceding non-comment line.
source: Fortran 2018 Standard, Section 6.3.3.3
Which character is used as statement-continuation marker, is up to the programmer and his style. Often you see a <ampersand>-character (&), or <dollar>-character ($) or the <asterisk>-character (*) like so:
c23456789012345678901234567890123456789012345678901234567890123456789012
g = something long
& + something_longer
& + something_even_longer
However, in the really old days, people often numbered their lines.
c23456789012345678901234567890123456789012345678901234567890123456789012
0g = something long
1 + something_longer
2 + something_even_longer
and because space was limited, they removed all spaces, which sometimes becomes very confusing when you have numbers in your line:
c23456789012345678901234567890123456789012345678901234567890123456789012
0g=1.2345+
10.35697-
22.5789
This does not add 10.35697 and subtract 22.5789, but adds 0.35697 and subtracts 2.5789
The usage of numbers as statement continuation markers is again inherited from the punched-cards. A single punched-card represented a single Fortran statement. And on the card, the row and column numbers were printed (Thanks to High Performance Mark for this information)
Note: the asterisk and slash in the OP are nothing more than the normal multiplication and division.

How does this GolfScript code print 1000 digits of pi?

How does this code work?
;''
6666,-2%{2+.2/#*\/10.3??2*+}*
`1000<~\;
It seem to use an array #* and a cycle {/**/}, but what is 6666? what is \/?
The first three characters; ;'', are unneeded for the program to function. They simply discard all input and replace it with an empty string, in case your compiler needs an input necessarily.
6666, prints out an array 6666 elements long, each of which are the numbers 0-6665.
-2% is a mapping function. It reverses the function and deletes every two elements. You now you have an array that is 3333 elements long, and it goes [6665 6663 6661 … 5 3 1]
{foo}* is a folding block call. For every element, do the following to the combination of elements. For example, 5,{+}* would add together the numbers 0-4.
So, let's see what we're doing in this folding block call.
2+ add two to the element.
. duplicate the element.
2/ halve it. Your sub-stack looks like this; (n+2),((n+2)/2)
# pulls the third element to the top.
This is the first function we cannot do, since our original stack is only two tall. We'll get back to this later.
*\/ will be skipped for now, we'll get back to it once we discuss folding more.
10.3?? Duplicate 10, then push a 3. [10 10 3]. ? is exponentiation, so we have [10 1000], then again gives us a 1 with 1000 zeroes afterwards.
2* Multiply it by two. So now we have a 2 with 1000 zeroes after.
+ Adds the rest of our math to 2e(1e3)
So, let's go back to that pesky #.
#*\/ will grab the third element and bring it to the top, then multiply it by the next top element ((n+2)/2), then we divide n by this number.
This is an expansion of the Leibniz Series.
\`1000< turns the int into a string, then throws a decimal after the 3.
~ dumps the string into a number again.
\; deleted the rest of the stack.
To answer your specific questions;
6666 was chosen, since half is 3333 (length of array), and we want more than pi times the number of digits of accuracy we want. We could make it smaller if we wanted, but 6666 is a cute number to use.
\/ Is the "inverse division" pair. Take a, take b, then calculate b/a. This is because the \ changes the order of the top two elements in the array, and / divides them.

The examine command in GDB confusion

When typing the examine command:
x/10xb 0xbffff450
It showed:
0xbffff450 : 8 bytes
0xbffff458 : 2 bytes
While typing:
x/10xw 0xbffff450
It shows:
0xbffff450 : 4 words
0xbffff460 : 4 words
0xbffff470 : 2 words
My questions are:
Why in the 1st case the next address was 0xbffff458 and in the 2nd was 0xbffff460?
Where is the in between addresses, I mean 0xbffff451,0xbffff452,...etc?
x/10xb $some_address shows the values at $some_address and 9 successive address locations incremented by byte as indicated by b in 10xb.
x/10xw $some_address on the other hand shows the values at $some_address and 9 successive address locations incremented by word length which is usually 4 bytes as indicated by w.
Coming back to your first question, it isn't like 0xbffff458 is the next address to 0xbffff450. The address shown on left is just indicative and corresponds to the first value seen on right. It is just a style of output and nothing else. Note that the word length is 4 bytes, so if 4 word values are shown starting from 0xbffff450, the next value corresponds to 0xbffff460 in hexadecimal format.
As for your 2nd question, those addresses are pretty much there and you can see their values by using examine.
Hope this helps!

Creating a MIPS instruction from binary in C / C++

I need to create a MIPs instruction from a name.bin file in C / C++
The only notable change in the instructions is that the first bit is a validation bit - 0 for invalid, 1 for valid
the format must display as such
1 00000 00001 00010 00011 00000 100000 ADD R3, R1, R2
I am using hexadecimal masks to find each part of the instruction ie: opcodeMask = 0x7C000000
however, I am having trouble implementing this idea and cannot figure out how to sort and print the binary code. Any insight would be greatly appreciated, Thanks!