ECE 5504 Fall 2023 Homework 2 PART I (60pt) 1. CISC (15pt) Let us begin by the following C code, which rotates the bits in a 32-bit value by n times. unsigned int rotate(unsigned int x, unsigned int n) { unsigned int msb; while (n != 0) { msb = x >> 31; x = (x << 1) | msb; n--; } return x; } The above loop compiles to the following x86 instruction sequence. On entry to this code, register %eax contains x and register %ecx contains n. loop: test %ecx,%ecx jz done mov %eax,%ebx shr $31,%ebx shl $1,%eax or %ebx,%eax dec %ecx jmp loop done: ... The meanings and instruction lengths of the instructions used above are given in the following table. Registers are denoted with RSUBSCRIPT, register contents with <RSUBSCRIPT>. Instruction Operation Length mov RSRC, RDEST <RDEST> = <RSRC> 2 bytes test RSRC1, RSRC2 temp = <RSRC1> & <RSRC2> Set flags based on value of temp 2 bytes dec RDEST <RDEST> = <RDEST> - 1 1 byte shl $imm8, RDEST <RDEST> = <RDEST> << imm32 2 bytes shr $imm8, RDEST <RDEST> = <RDEST> >> imm32 2 bytes or RSRC, RDEST <RDEST> = <RDEST> | <RSRC> 2 bytes jmp label jump to the address specified by label 2 bytes jz label if (ZF == 1), jump to the address specified by label 2 bytes a. (5pt) How many bytes are there in the program in total? b. (5pt) For the above x86 assembly code, how many bytes of instructions need to be fetched if n = 5? (hint: the loop will iterate for n times, and execute the test and jz to end the loop) c. (5pt) Assuming 32-bit data values, how many bytes of data memory need to be loaded? Stored? 2. RISC (25pt) a. (5pt) Translate each of the x86 instructions in the following table into RISC-V instructions. Use the following RISC-V instructions, and fill in the RISC-V instruction sequence in the table: or x1, x6, x1 srli x6, x1, 31 slli x1, x1, 1 addi x2, x2, -1 jal x0, loop beq x2, x0 done Assume that register x1 contains value x upon entry, and register x2 receive value n. Use registers x6, x7, etc., for temporaries. References about RISC-V instructions: https://www.cl.cam.ac.uk/teaching/1617/ECAD+Arch/files/docs/RISCVGreenCardv8-20151013.pdf x86 Assembly RISC-V Assembly Label test %ecx,%ecx jz done loop: RISC-V instruction sequence mov $eax,%ebx shr $31,%ebx shl $1,%eax or %ebx,%eax dec %ecx jmp loop ... … done: … a. (5pt) Which register holds the value of msb in the above RISC-V code? b. (5pt) How many bytes is the RISC-V program using your direct translation? c. (5pt) How many bytes of RISC-V instructions need to be fetched for n = 5 with your direct translation? d. (5pt) Assuming 32-bit data values, how many bytes of data memory need to be loaded? Stored? 3. Iron law of processor performance (20pt) Mark whether the following modifications will cause each of the first three categories to increase, decrease, or whether the modification will have no effect. Explain your reasoning. For the final column “Overall Performance”, mark whether the following modifications increase, decrease, have no effect, or whether the modification will have an ambiguous effect. Explain your reasoning. If the modification has an ambiguous effect, describe the tradeoff in which it would be a beneficial modification or in which it would be a detrimental modification (i.e., as an engineer would you suggest using the modification or not and why?). Instructions / Program a. b. Cycles / Instruction (5pt) Adding three NOP instructions after each branch instruction (hint: hazards in pipeline) (5pt) Reduce (hint: data Seconds / Cycle Overall Performance number of registers in the ISA c. d. hazards in pipeline) (5pt) Improving memory access speed (5pt) Adding 16bit versions of the most common instructions in RISC-V (normally 32 bits in length) to the ISA (i.e., make RISC-V a variable-length ISA) (hint: latency of instruction fetch) PART II (40pt) The goal of this part is to compare the differences in ISA between RISCV and x86. Just follow the following steps: 1. We will be using the same matrix multiplication code to compare the two ISA’s. Use the following link to accept the assignment and clone the required source code file and Makefile for this programming task in your /home/rocket directory. - https://code.vt.edu/ece5504_f23/ece5504-fall23-lab2 2. X86 compilation: Use the native GCC compiler, compile the multiplication.c to generate the object file. Then use the objdump command to generate the object-dump file. $ cd ~/ece5504-fall23-lab2 $ gcc multiplication.c -O0 -o multiplication $ objdump -d multiplication > multiplication_x86.dump 3. RISC-V compilation: We have prepared a makefile for you. You have to run the Makefile. Make sure to run the source command whenever you log back into the session/server. $ source ~/rocket/chipyard-clean/env.sh $ make 4. Upon running the Makefile, you should see two additional files in the same directory. One is the binary file (multiplication.riscv) and the other is the objdump file (multiplication.dump). These files are generated when the matrix multiplication is compiled using the RISCV-GCC. 5. Now there is a way to compile the source code using the full 32-bit instruction set in RISCV architecture. Just run the following make command in the same directory as before. $ make uncompressed You will see a new objdump file (multiplication_uncompressed.dump) in the same folder. 6. After doing this you will have a total of three objdump files, one compiled with native GCC compiler and the other two with RISCV-GCC. Compare only the multiplication function in all these files and summarize your conclusions. 7. Look for the multiplication functions. In the dump files, search for: <multiplication>: In all the .dump files the starting of the function should look like the following: Now look at the assembly of the multiplication function a. (12pt) How many bytes are there for the multiplication function? in x86 and RISC-V (with and b. c. d. e. f. without the uncompressed instructions) (5pt) How many bytes are there in the longest instruction in x86 executable? How about the shortest instruction? (5pt) How many bytes are there in the instruction in RISC-V? Describe the difference between the two compilation options (make vs make uncompressed). Why are they different? (6pt) What is the multiplication instruction in the objdump? (x86, RISC-V) (show the machine code and assembly) (6pt) For the x86 instruction in (d), look up the encoding of the multiplication instruction. https://c9x.me/x86/html/file_module_x86_id_138.html i. What is the opcode for the multiplication instruction in binary? ii. What are the source registers? i.e., which two registers hold the inputs. iii. What is the destination register? i.e., which register holds the product of the multiplication. (6pt) For the RISC-V instruction in (d), look up RISC-V for the encoding of the multiplication instruction. https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf i. What is the opcode for the multiplication instruction in binary? ii. iii. What are the source registers? i.e., which two registers hold the inputs. What is the destination register? i.e., which register holds the product of the multiplication. PART III 1. How long did it take for you to complete the assignment? 2. Do you have any suggestions for the course?