// File: /workspace/github_c_makefile_star2_O0/hamsternz[P]emulate-risc-v/clint.c
// Function: CLINT_get
int CLINT_get(struct region *r, uint32_t address, uint32_t *value) {
   uint32_t v = 0;
   char buffer[100];
   if((address & 3) != 0) {
     fprintf(stderr,"Unaligned memory read 0x%08x\n", r->base+address);
     return 0;
   }

   if(address+4 > r->size) {
     fprintf(stderr,"Memory region boundary crossed at 0x%08x\n", r->base+address);
     return 0;
   }

   v = ((unsigned char *)r->data)[address]; 
   v = v + (((unsigned char *)r->data)[address+1] << 8); 
   v = v + (((unsigned char *)r->data)[address+2] << 16); 
   v = v + (((unsigned char *)r->data)[address+3] << 24); 

   switch(address) {
     case 0x0000: // MSIP regs
        *value = v;
	break;
     case 0x4000: // Timer Compare Reg
        *value = v;
	break;
     case 0x4004:
        *value = v;
	break;
     case 0xBFF8:   // Cycle count
        *value = riscv_cycle_count_l();
	break;
     case 0xBFFC:
        *value = riscv_cycle_count_h();
	break;
     default:
        sprintf(buffer,"CLINT Rd of non-register address 0x%08x", address);
        display_log(buffer);
	*value = 0;
	return 1;
   }
     
   sprintf(buffer,"CLINT Rd address 0x%08x: 0x%08x", address, v);
   display_log(buffer);

   return 1;
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x88(%rsp)
movl %esi, 0x84(%rsp)
movq %rdx, 0x78(%rsp)
movl $0x0, 0x74(%rsp)
movl 0x84(%rsp), %eax
andl $0x3, %eax
cmpl $0x0, %eax
je 0x845c
movq 0x5bcf(%rip), %rax      # 0xdff8
movq (%rax), %rdi
movq 0x88(%rsp), %rax
movl 0x8(%rax), %edx
addl 0x84(%rsp), %edx
leaq 0x2b35(%rip), %rsi      # 0xaf7a
movb $0x0, %al
callq 0x2130
movl $0x0, 0x94(%rsp)
jmp 0x8637
movl 0x84(%rsp), %eax
addl $0x4, %eax
movq 0x88(%rsp), %rcx
cmpl 0xc(%rcx), %eax
jbe 0x84ad
movq 0x5b7e(%rip), %rax      # 0xdff8
movq (%rax), %rdi
movq 0x88(%rsp), %rax
movl 0x8(%rax), %edx
addl 0x84(%rsp), %edx
leaq 0x2a9b(%rip), %rsi      # 0xaf31
movb $0x0, %al
callq 0x2130
movl $0x0, 0x94(%rsp)
jmp 0x8637
movq 0x88(%rsp), %rax
movq 0x38(%rax), %rax
movl 0x84(%rsp), %ecx
movzbl (%rax,%rcx), %eax
movl %eax, 0x74(%rsp)
movl 0x74(%rsp), %eax
movq 0x88(%rsp), %rcx
movq 0x38(%rcx), %rcx
movl 0x84(%rsp), %edx
incl %edx
movzbl (%rcx,%rdx), %ecx
shll $0x8, %ecx
addl %ecx, %eax
movl %eax, 0x74(%rsp)
movl 0x74(%rsp), %eax
movq 0x88(%rsp), %rcx
movq 0x38(%rcx), %rcx
movl 0x84(%rsp), %edx
addl $0x2, %edx
movzbl (%rcx,%rdx), %ecx
shll $0x10, %ecx
addl %ecx, %eax
movl %eax, 0x74(%rsp)
movl 0x74(%rsp), %eax
movq 0x88(%rsp), %rcx
movq 0x38(%rcx), %rcx
movl 0x84(%rsp), %edx
addl $0x3, %edx
movzbl (%rcx,%rdx), %ecx
shll $0x18, %ecx
addl %ecx, %eax
movl %eax, 0x74(%rsp)
movl 0x84(%rsp), %eax
movl %eax, 0xc(%rsp)
testl %eax, %eax
je 0x8581
jmp 0x854d
movl 0xc(%rsp), %eax
subl $0x4000, %eax           # imm = 0x4000
je 0x858e
jmp 0x855a
movl 0xc(%rsp), %eax
subl $0x4004, %eax           # imm = 0x4004
je 0x859b
jmp 0x8567
movl 0xc(%rsp), %eax
subl $0xbff8, %eax           # imm = 0xBFF8
je 0x85a8
jmp 0x8574
movl 0xc(%rsp), %eax
subl $0xbffc, %eax           # imm = 0xBFFC
je 0x85b8
jmp 0x85c8
movl 0x74(%rsp), %ecx
movq 0x78(%rsp), %rax
movl %ecx, (%rax)
jmp 0x8604
movl 0x74(%rsp), %ecx
movq 0x78(%rsp), %rax
movl %ecx, (%rax)
jmp 0x8604
movl 0x74(%rsp), %ecx
movq 0x78(%rsp), %rax
movl %ecx, (%rax)
jmp 0x8604
callq 0x3140
movl %eax, %ecx
movq 0x78(%rsp), %rax
movl %ecx, (%rax)
jmp 0x8604
callq 0x3150
movl %eax, %ecx
movq 0x78(%rsp), %rax
movl %ecx, (%rax)
jmp 0x8604
leaq 0x10(%rsp), %rdi
movl 0x84(%rsp), %edx
leaq 0x31e4(%rip), %rsi      # 0xb7bf
movb $0x0, %al
callq 0x21e0
leaq 0x10(%rsp), %rdi
callq 0x6b20
movq 0x78(%rsp), %rax
movl $0x0, (%rax)
movl $0x1, 0x94(%rsp)
jmp 0x8637
leaq 0x10(%rsp), %rdi
movl 0x84(%rsp), %edx
movl 0x74(%rsp), %ecx
leaq 0x31cc(%rip), %rsi      # 0xb7e7
movb $0x0, %al
callq 0x21e0
leaq 0x10(%rsp), %rdi
callq 0x6b20
movl $0x1, 0x94(%rsp)
movl 0x94(%rsp), %eax
addq $0x98, %rsp
retq
nopw %cs:(%rax,%rax)