-
Notifications
You must be signed in to change notification settings - Fork 18
riscv64memo
tyfkda edited this page Sep 12, 2024
·
28 revisions
Regs. | Alias | Purpose | Save |
---|---|---|---|
x0 |
zero |
Zero | -- |
x1 |
ra |
Return Address | Caller |
x2 |
sp |
Stack Pointer | Callee |
x3 |
gp |
Global Pointer | -- |
x4 |
tp |
Thread Pointer | -- |
x5 |
t0 |
Temporary, alternate link register | Caller |
x6 ~x7
|
t1 ~t2
|
Temporaries | Caller |
x8 |
s0/fp |
Saved, Frame Pointer | Callee |
x9 |
s1 |
Saved Register | Callee |
x10 ~x17
|
a0 ~a7
|
Function Parameter Register | Caller |
x18 ~x27
|
s2 ~s11
|
Saved Register | Callee |
x28 ~x31
|
t3 ~t6
|
Temporaries | Caller |
RISC-V Instruction Set Specifications
-
li
: load immediate (~32bit) add
Bxx
Opcode | Condition |
---|---|
beq |
== |
bne |
!= |
blt |
< |
bge |
>= |
bltu |
< (unsigned) |
bgeu |
>= (unsigned) |
- FP registers: Use
feq.d
to get condition to GP register, andbne
Pseudo Instruction | Expansion | Function |
---|---|---|
nop | addi x0, x0, 0 | No operation |
li rd, immediate | Myriad sequences | Load immediate |
mv rd, rs | addi rd, rs, 0 | Copy register |
not rd, rs | xori rd, rs, -1 | One’s complement |
neg rd, rs | sub rd, x0, rs | Two’s complement |
negw rd, rs | subw rd, x0, rs | Two’s complement word |
sext.w rd, rs | addiw rd, rs, 0 | Sign extend word |
seqz rd, rs | sltiu rd, rs, 1 | Set if = zero |
snez rd, rs | sltu rd, x0, rs | Set if ̸= zero |
sltz rd, rs | slt rd, rs, x0 | Set if < zero |
sgtz rd, rs | slt rd, x0, rs | Set if > zero |
beqz rs, offset | beq rs, x0, offset | Branch if = zero |
bnez rs, offset | bne rs, x0, offset | Branch if ̸= zero |
blez rs, offset | bge x0, rs, offset | Branch if ≤ zero |
bgez rs, offset | bge rs, x0, offset | Branch if ≥ zero |
bltz rs, offset | blt rs, x0, offset | Branch if < zero |
bgtz rs, offset | blt x0, rs, offset | Branch if > zero |
bgt rs, rt, offset | blt rt, rs, offset | Branch if > |
ble rs, rt, offset | bge rt, rs, offset | Branch if ≤ |
bgtu rs, rt, offset | bltu rt, rs, offset | Branch if >, unsigned |
bleu rs, rt, offset | bgeu rt, rs, offset | Branch if ≤, unsigned |
j offset | jal x0, offset | Jump |
jal offset | jal x1, offset | Jump and link |
jr rs | jalr x0, 0(rs) | Jump register |
jalr rs | jalr x1, 0(rs) | Jump and link register |
ret | jalr x0, 0(x1) | Return from subroutine |
call aa | auipc x1, aa[31 : 12] + aa[11] | Call far-away subroutine |
jalr x1, aa[11:0](x1) | (two instructions) | |
tail aa | auipc x6, aa[31 : 12] + aa[11] | Tail call far-away subroutine |
jalr x0, aa[11:0](x6) | (also two instructions) |
-
nop
:00 00 00 13
- 疑問:
call
はauipc
でra
レジスタにPC相対を入れるが、呼び出し先のアドレス計算はどうなってるのか?- リンク後は
jal ra, offset
に切り詰められている(オフセットが短い場合)。その場合にはPCを部分的に書き換えるようなことはないので、リターンアドレスも現在のPCを入れるだけなので問題はない。
- リンク後は
More:
Pseudo Instruction | Expansion | Function |
---|---|---|
fmv.d rd, rs | fsgnj.d rd, rs, rs | Copy FP register |
fneg.d rd, rs | fsgnjn.d rd, rs, rs | Negate FP register |
- Chapter 18. Calling Convention: https://riscv.org/wp-content/uploads/2015/01/riscv-calling.pdf
- RISC-V Sign Extension Optimizations: https://llvm.org/devmtg/2022-11/slides/TechTalk21-RISC-VSignExtensionOptimizations.pdf
- 任意超引数の関数の場合、浮動小数点数レジスタではなく汎用レジスタで渡すっぽい?
-
sizesof(va_list)
=8
-
va_list
自体は単なるポインタ?で実体はスタックフレーム上に別に保持している? - スタック引数も扱えるようにするため、レジスタ引数の待避をスタックフレームの底に配置する必要がある。
format | bit31-25 | 24-20 | 19-15 | 14-12 | 11-7 | 6-0 |
---|---|---|---|---|---|---|
R-Type | funct7 | rs2 | rs1 | funct3 | rd | Opcode(7) |
I-Type | > | imm[11:0] | rs1 | funct3 | rd | Opcode(7) |
S-Type | imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | Opcode(7) |
B-Type | imm[12],[10:5] | rs2 | rs1 | funct3 | imm[4:1],[11] | Opcode(7) |
U-Type | > | > | > | imm[31:12] | rd | Opcode(7) |
J-Type | > | > | > | imm[20],[10:1],[11],[19:12] | rd | Opcode(7) |
TODO: 圧縮形式、それとのバイナリレベルでの判別法
-
All Aboard, Part 3: Linker Relaxation in the RISC-V Toolchain
R_RISCV_RELAX
- RISC-V ELF Specification
-
Design of R_RISCV_PCREL_LO12 どうして対応するHI20を指す形なのか、わからず
- LO12時点でのPCからの相対ではなく、HI20時点での相対を計算する必要があるから?
//