// Trivial example program for testing RISC-V compilation. #include int sumarray_c(int *a, int n) { int total = 0; for (int i = 0; i != n; i++) total += a[i]; return total; } // That disassembles as follows with GCC 12.2.0: // // 00000000000007e8 : // 7e8: 872a mv a4,a0 ; free up return value slot by moving a into a4 (ABI design blunder) // 7ea: 4781 li a5,0 ; i = 0 // 7ec: 4501 li a0,0 ; total = 0 // 7ee: 0007869b sext.w a3,a5 ; convert 32-bit a5 to 64-bit a3 (unnecessary but GCC doesn’t know this; size_t counters would avoid) // 7f2: 00d59363 bne a1,a3,7f8 ; continue loop if i != n // 7f6: 8082 ret ↑ ; return total if exiting // 7f8: 00279693 sll a3,a5,0x2 | ; convert i to byte index into int array (because RISC-V doesn't have a shifted offset load) // 7fc: 96ba add a3,a3,a4 | ; compute &a[i] // 7fe: 4294 lw a3,0(a3) | ; load a[i] // 800: 0785 add a5,a5,1 | ; increment i (could be strength-reduced) // 802: 9d35 addw a0,a0,a3 | ; add loaded a[i] to total // 804: b7ed j 7ee ____| ; next loop iteration // That suggests writing the code as follows: int sumarray_opt(int *a, int n) { int total = 0; for (int *end = a + n; a != end; a++) total += *a; return total; } // This results in the following: // // 0000000000000806 : // 806: 058a sll a1,a1,0x2 // 808: 87aa mv a5,a0 // 80a: 95aa add a1,a1,a0 // 80c: 4501 li a0,0 // 80e: 00b79363 bne a5,a1,814 // 812: 8082 ret ↑ // 814: 4398 lw a4,0(a5) | // 816: 0791 add a5,a5,4 | // 818: 9d39 addw a0,a0,a4 | // 81a: bfd5 j 80e ____| // // This reduces the inner loop from 7 instructions executed to 5. For // ARM Cortex-M4, GCC compiles both subroutines to the same code, // using ARM’s postincrement mode and precomputing the loop limit as a // pointer: // // 00000678 : // 678: 4603 mov r3, r0 // 67a: eb00 0181 add.w r1, r0, r1, lsl #2 // 67e: 2000 movs r0, #0 // 680: 428b cmp r3, r1 // 682: d100 bne.n 686 // 684: 4770 bx lr // 686: f853 2b04 ldr.w r2, [r3], #4 // 68a: 4410 add r0, r2 // 68c: e7f8 b.n 680 int main(int argc, char **argv) { int a[128]; int n = 0; do { printf("? "); fflush(stdout); } while (1 == scanf("%d", &a[n++])); printf("%d\n", sumarray_opt(a, n)); return 0; }