# Assignment1: RISC-V Assembly and Instruction Pipeline contributed by < `曾俊瑋` > ## Quiz1 Problem C ### C code for function fabsf The fabsf function is used to clear the sign bit for the absolute value. ```clike= static inline float fabsf(float x) { uint32_t i = *(uint32_t *)&x; // Read the bits of the float into an integer i &= 0x7FFFFFFF; // Clear the sign bit to get the absolute value x = *(float *)&i; // Write the modified bits back into the float return x; } ``` :::danger Don't paste code snip without comprehensive discussions. ::: ### C code for function my_clz This code is used to count the number of leading zero bits in the binary representation of an unsigned integer. ```clike= static inline int my_clz(uint32_t x) { int count = 0; for (int i = 31; i >= 0; --i) { if (x & (1U << i)) break; count++; } return count; } ``` ### C code for function fp16_to_fp32 Implement the fp16_to_fp32 function, which converts a 16-bit floating-point number in IEEE half-precision format (bit representation) to a 32-bit floating-point number in IEEE single-precision format (bit representation). ```clike= static inline uint32_t fp16_to_fp32(uint16_t h) { const uint32_t w = (uint32_t) h << 16; const uint32_t sign = w & UINT32_C(0x80000000); const uint32_t nonsign = w & UINT32_C(0x7FFFFFFF); uint32_t renorm_shift = my_clz(nonsign); renorm_shift = renorm_shift > 5 ? renorm_shift - 5 : 0; const int32_t inf_nan_mask = ((int32_t)(nonsign + 0x04000000) >> 8) & INT32_C(0x7F800000); const int32_t zero_mask = (int32_t)(nonsign - 1) >> 31; return sign | ((((nonsign << renorm_shift >> 3) + ((0x70 - renorm_shift) << 23)) | inf_nan_mask) & ~zero_mask); } ``` ### Assembly code ```clike= .data x: .word 0xffff str1: .string "\nAbsolute value is " str2: .string "\nNumber of zero is " str3: .string "\nUndefined" str4: .string "\nfp16_to_fp32 result is " .text main: # Load x into a0,run function fabsf lw a0, x jal ra, fabsf # Run function my_clz la a0,str2 # Print string2 jal ra, Print_str lw a0, x # Load x0 into a0 and call function my_clz jal ra, my_clz li a7, 1 ecall # Run function fp16_to_fp32 la a0,str4 # Print string3 jal ra, Print_str lw a0, x # Load x0 into a0 and call function fp16_to_fp32 jal ra, fp16_to_fp32 li a7, 34 ecall li a7, 10 ecall # Function fabsf fabsf: li a1, 0x7FFFFFFF # set a1=0x7FFFFFFF li a7, 34 # print x ecall and t0, a0, a1 # x & 0x7FFFFFFF la a0,str1 # Load the address of string1 li a7, 4 # Print string1 ecall mv a0, t0 # Move the result to a0 for printing li a7, 34 # Print the result ecall ret # Function my_clz my_clz: li a1, 31 # Set a1 = 31 add a2, x0, x0 # Set a2 = 0 (result) bne a0,zero,Loop # Check x = 0? li a2,-1 la a0, str3 # x = 0,print "undefined" li a7, 4 # System call code for printing an integer ecall ret # Break Loop: blt a1, zero,End_Loop # If a1 < 0,break the loop li t0,1 # Set t0 = 1 sll t1,t0, a1 # Set t1 = 0 << a1 and t2,a0, t1 # t2 = x & t1 bnez t2,End_Loop # If t2 = true,break the loop addi a2, a2, 1 # a2 ++ addi a1, a1, -1 # a1 - 1 j Loop End_Loop: mv a0, a2 ret # Function fp16_to_fp32 fp16_to_fp32: lw a0, x slli s1, a0, 16 # s1 = w li t0, 0x80000000 and s2, s1, t0 # s2 = sign li t0, 0x7FFFFFFF and s3, s1, t0 # s3 = nonsign mv sp,ra mv a0,s3 jal ra, my_clz li t0, 5 li s4, 0 # s4 = renorm blt a2, t0,mask addi s4, a2, -5 mask: li t0, 0x4000000 add s5, s3, t0 srai s5, s5, 8 li t0, 0x7F800000 and s5, s5, t0 # s5 = inf_nan addi s6, s3, -1 srli s6, s6, 31 # s6 = zero_mask sll s3, s3, s4 srli s3, s3 ,3 li t0,0x70 sub t1, t0, s4 slli t1, t1, 23 add s3, s3, t1 or s3, s3, s5 xori s6, s6, -1 and t1, t1, s6 or s2, s2, s3 mv a0, s2 jr sp # Function Print string Print_str: li a7, 4 ecall ret ``` ## Leetcode Problem 2980 : Check if Bitwise OR Has Trailing Zeros Given an array of positive integers. Check if it is possible to select two or more elements in the array such that the bitwise OR of the selected elements has at least one trailing zero in its binary representation. ### C code Because the binary representation of even number ends with 0,we just need to check whether the array has two or more even number. ```clike= bool hasTrailingZeros(int* nums, int numsSize) { int count = 0; for(int i=0; i<numsSize; i++) { if(!(nums[i]&1)) count++; if(count>=2) return true; } return false; } ``` ### Assembly code ```clike= .data test1: .word 1,2,3,4,5 str1: .string "TRUE" str2: .string "FALSE" .text main: la a0, test1 # Load input data li a1, 5 # Load input data length jal ra, hasTrailingZeros # Call function li a7, 4 ecall li a7, 10 # Exit Program ecall hasTrailingZeros: mv s1, a0 mv t0, a1 li t1, 0 li t2, 0 Loop: # for(t1=0;t1<t0;t1++) li t3, 2 lw t4,0(s1) # t4=test1[t1] andi t4, t4, 1 # t4&1 bne t4, zero, Else # if t4 is even, t2++ addi t2, t2, 1 Else: bge t2, t3, End_Loop # If has 2 even number,close loop addi s1, s1, 4 # Move to next address addi t1, t1, 1 blt t1, t0,Loop la a0, str2 # Return False (li a0, zero) ret End_Loop: la a0, str1 # Return True (li a0, 1) ret ```