riscv-non-isa / riscv-asm-manual

RISC-V Assembly Programmer's Manual
https://jira.riscv.org/browse/RVG-4
Creative Commons Attribution 4.0 International
1.44k stars 238 forks source link

how does `%hi` work for RISC-V 64? #63

Closed PeterlitsZo closed 3 years ago

PeterlitsZo commented 3 years ago

I know that %hi(symbol) will get the high 20 bits of the symbols' address and then be as a immediate number in RISC-V 32. In short, take the [31:12] bits in RISC-V 32.

But in RISC-V 64, will it get the [31:12] bits, or just get the [63:44] bits?

Thanks for your help.

PeterlitsZo commented 3 years ago

BTW, if I want to test something, which tools can help me please? Which tools can run the ASM code?

jim-wilson commented 3 years ago

%hi is always bits 31:12. However it is a little more complicated than that, since we always use lui with an add, so if the low 12 bits are equal to or greater than 0x800 then we need to round the %hi value up by one, and then use a negative value for the %lo.

If you assemble and link asm code, then it can be run in any smiulator. We have spike (riscv-isa-sim) which is best for hardware folk, qemu which is best for software folk, and a gdb sim which is useful if you are familiar with it.

PeterlitsZo commented 3 years ago

%hi is always bits 31:12. However it is a little more complicated than that, since we always use lui with an add, so if the low 12 bits are equal to or greater than 0x800 then we need to round the %hi value up by one, and then use a negative value for the %lo.

If you assemble and link asm code, then it can be run in any smiulator. We have spike (riscv-isa-sim) which is best for hardware folk, qemu which is best for software folk, and a gdb sim which is useful if you are familiar with it.

Thanks for your valuable reply! I will close this issue soon.

PeterlitsZo commented 3 years ago

I build a test toolchain on my machine, and run:

# 0xffff_ffff_8000_0000
lui a0, %hi(0xffffffff80000000)
call print_num
-------------------------------------------
number: ffffffff80000000
# 0xffff_ffff_7000_0000
lui a0, %hi(0xffffffff70000000)
call print_num
-------------------------------------------
number: 70000000

That looks like the [63:32] bits are same as the 31 bit in function %hi, and do you know why it works like this please? Thanks.

johnwinans commented 3 years ago

Because the immediate operand in the lui instruction is sign-extended to XLEN before it is stored into rd. Note this is true for every instruction that has an imm field.

PeterlitsZo commented 3 years ago

Thanks for your kindly help!