feat(asm): emit RISC-V GOOBJ with the shared emitter
Assisted-by: DeepSeek V4 Pro
This commit is contained in:
+15
-14
@@ -91,9 +91,12 @@ func assembleRISCV(t *ast.Text) ([]byte, map[string]int, []Reloc, error) {
|
||||
code = []byte{byte(c16), byte(c16 >> 8)}
|
||||
}
|
||||
// Make newly added relocation offsets absolute (subtract prologue to make
|
||||
// them function-relative, then the caller adds fn.Offset).
|
||||
// them function-relative, then the caller adds fn.Offset). After
|
||||
// points just past the AUIPC+second-instruction pair, which is
|
||||
// always 8 bytes wide for these static-symbol references.
|
||||
for j := preCount; j < len(relocs); j++ {
|
||||
relocs[j].Off += pc - len(prologue)
|
||||
relocs[j].After = relocs[j].Off + 8
|
||||
}
|
||||
preCount = len(relocs)
|
||||
out = append(out, code...)
|
||||
@@ -608,39 +611,37 @@ func encodeRISCVLoadImm(rd int, imm int32) []byte {
|
||||
}
|
||||
|
||||
// encodeRISCVSBAddr emits AUIPC + ADDI to load the address of a static
|
||||
// symbol into rd. Records R_RISCV_PCREL_HI20 + R_RISCV_PCREL_LO12_I relocs.
|
||||
// symbol into rd, recording the single R_RISCV_PCREL_ITYPE relocation the Go
|
||||
// toolchain uses for the pair (the object-file emitters expand or map it).
|
||||
func encodeRISCVSBAddr(sym *ast.Symbol, rd int, relocs *[]Reloc) []byte {
|
||||
name := sym.Name
|
||||
if relocs != nil {
|
||||
*relocs = append(*relocs, Reloc{Off: 0, After: 0, Name: name, Kind: RelPCRelHI20})
|
||||
*relocs = append(*relocs, Reloc{Off: 4, After: 4, Name: name, Kind: RelPCRelLO12})
|
||||
*relocs = append(*relocs, Reloc{Off: 0, After: 8, Name: name, Kind: RelRISCVPCRELIType, Addend: sym.Offset})
|
||||
}
|
||||
auipc := riscvUType(riscvEnc{0x17, 0x0, 0x00}, rd, 0)
|
||||
addi := riscvIType(riscvEnc{0x13, 0x0, 0x00}, rd, rd, 0)
|
||||
return append(wordLE(auipc), wordLE(addi)...)
|
||||
}
|
||||
|
||||
// encodeRISCVSBLoad emits AUIPC + LD to load from a static symbol into rd.
|
||||
// Records R_RISCV_PCREL_HI20 + R_RISCV_PCREL_LO12_I relocs.
|
||||
// encodeRISCVSBLoad emits AUIPC + LD to load from a static symbol into rd,
|
||||
// recording the single R_RISCV_PCREL_ITYPE relocation for the pair.
|
||||
func encodeRISCVSBLoad(sym *ast.Symbol, rd int, relocs *[]Reloc) []byte {
|
||||
name := sym.Name
|
||||
if relocs != nil {
|
||||
*relocs = append(*relocs, Reloc{Off: 0, After: 0, Name: name, Kind: RelPCRelHI20})
|
||||
*relocs = append(*relocs, Reloc{Off: 4, After: 4, Name: name, Kind: RelPCRelLO12})
|
||||
*relocs = append(*relocs, Reloc{Off: 0, After: 8, Name: name, Kind: RelRISCVPCRELIType, Addend: sym.Offset})
|
||||
}
|
||||
auipc := riscvUType(riscvEnc{0x17, 0x0, 0x00}, rd, 0)
|
||||
ld := riscvIType(riscvEnc{0x03, 0x3, 0x00}, rd, rd, 0)
|
||||
return append(wordLE(auipc), wordLE(ld)...)
|
||||
}
|
||||
|
||||
// encodeRISCVSBStore emits AUIPC + SD to store a register into a static symbol.
|
||||
// Records R_RISCV_PCREL_HI20 + R_RISCV_PCREL_LO12_S relocs.
|
||||
// encodeRISCVSBStore emits AUIPC + SD to store a register into a static symbol,
|
||||
// recording the single R_RISCV_PCREL_STYPE relocation for the pair.
|
||||
func encodeRISCVSBStore(sym *ast.Symbol, rs2 int, relocs *[]Reloc) []byte {
|
||||
tmp := 31 // X31 = T6
|
||||
name := sym.Name
|
||||
if relocs != nil {
|
||||
*relocs = append(*relocs, Reloc{Off: 0, After: 0, Name: name, Kind: RelPCRelHI20})
|
||||
*relocs = append(*relocs, Reloc{Off: 4, After: 4, Name: name, Kind: RelPCRelLO12S})
|
||||
*relocs = append(*relocs, Reloc{Off: 0, After: 8, Name: name, Kind: RelRISCVPCRELSType, Addend: sym.Offset})
|
||||
}
|
||||
auipc := riscvUType(riscvEnc{0x17, 0x0, 0x00}, tmp, 0)
|
||||
sd := riscvSType(riscvEnc{0x23, 0x3, 0x00}, tmp, rs2, 0)
|
||||
@@ -687,8 +688,8 @@ func tryCompressRVC(instr *ast.Instr, fi riscvFrameInfo) (uint16, bool) {
|
||||
|
||||
switch mnem {
|
||||
case "RET":
|
||||
// RET = JALR X0, 0(X1) → C.JR RA (CR-type: funct4=0x8, rd=0, rs2=1)
|
||||
return rvcCR(0x8, 0, 1), true
|
||||
// RET = JALR X0, 0(X1) → C.JR RA (CR-type: funct4=0x8, rs1=ra, rs2=0).
|
||||
return rvcCR(0x8, 1, 0), true
|
||||
|
||||
case "LD", "MOV":
|
||||
// LD rd, offset(SP) → C.LDSP when rd≠0 and uimm[8:3] fits.
|
||||
|
||||
Reference in New Issue
Block a user