mirror of
https://github.com/odin-lang/Odin.git
synced 2026-07-12 19:00:28 +00:00
rexcode/mips: R6 PC-relative loads LWPC/LWUPC/LDPC
New REL19/REL18 operand types + BRANCH_19/BRANCH_18 encodings + REL_PC19/ REL_PC18 relocations (R6 PC-relative semantics: offset is relative to the instruction's own address, no delay-slot adjustment; LDPC aligns the PC down to 8 and scales by 8). LWPC (mips32r6), LWUPC/LDPC (mips64r6). Byte-exact vs llvm-mc and decode-clean; 281 tests green.
This commit is contained in:
@@ -267,6 +267,18 @@ extract_operand_inline :: #force_inline proc "contextless" (
|
||||
if rel26 & (1 << 25) != 0 { rel26 |= ~i32(0x3FFFFFF) }
|
||||
target := u32(i32(pc) + 4 + (rel26 << 2))
|
||||
return Operand{relative = i64(target), kind = .RELATIVE, size = 4}
|
||||
case .BRANCH_19:
|
||||
// R6 PC-relative load: relative to this instruction (no +4), << 2.
|
||||
rel19 := i32(word & 0x7FFFF)
|
||||
if rel19 & (1 << 18) != 0 { rel19 |= ~i32(0x7FFFF) }
|
||||
target := u32(i32(pc) + (rel19 << 2))
|
||||
return Operand{relative = i64(target), kind = .RELATIVE, size = 4}
|
||||
case .BRANCH_18:
|
||||
// LDPC: relative to this instruction aligned down to 8, << 3.
|
||||
rel18 := i32(word & 0x3FFFF)
|
||||
if rel18 & (1 << 17) != 0 { rel18 |= ~i32(0x3FFFF) }
|
||||
target := u32((i32(pc) &~ i32(7)) + (rel18 << 3))
|
||||
return Operand{relative = i64(target), kind = .RELATIVE, size = 4}
|
||||
|
||||
// Misc small immediates -------------------------------------------------
|
||||
case .FCC_BC:
|
||||
|
||||
@@ -225,7 +225,7 @@ operand_matches_inline :: #force_inline proc "contextless" (
|
||||
case .IMM5, .IMM16S, .IMM16U, .IMM20, .IMM26, .SEL, .FCC,
|
||||
.GTE_SF, .GTE_MX, .GTE_V, .GTE_CV, .GTE_LM:
|
||||
return op.kind == .IMMEDIATE
|
||||
case .REL16, .REL21, .REL26, .REL_J26:
|
||||
case .REL16, .REL21, .REL26, .REL_J26, .REL19, .REL18:
|
||||
return op.kind == .RELATIVE
|
||||
case .MEM:
|
||||
return op.kind == .MEMORY
|
||||
@@ -310,6 +310,18 @@ pack_operand_inline :: #force_inline proc(
|
||||
type = .REL26, size = 4, inst_idx = inst_idx,
|
||||
})
|
||||
return 0
|
||||
case .BRANCH_19:
|
||||
append(relocs, Relocation{
|
||||
offset = pc, label_id = u32(op.relative),
|
||||
type = .REL_PC19, size = 4, inst_idx = inst_idx,
|
||||
})
|
||||
return 0
|
||||
case .BRANCH_18:
|
||||
append(relocs, Relocation{
|
||||
offset = pc, label_id = u32(op.relative),
|
||||
type = .REL_PC18, size = 4, inst_idx = inst_idx,
|
||||
})
|
||||
return 0
|
||||
|
||||
// FP condition-code field (BC1*, MOVF/MOVT, C.cond.fmt).
|
||||
case .FCC_BC:
|
||||
@@ -492,6 +504,36 @@ resolve_relocation_inline :: #force_inline proc(
|
||||
}
|
||||
word = (word &~ 0x3FFFFFF) | (u32(rel) & 0x3FFFFFF)
|
||||
|
||||
case .REL_PC19:
|
||||
// R6 PC-relative load: offset is relative to the instruction's own
|
||||
// address (no delay-slot adjustment), scaled by 4, 19-bit signed.
|
||||
rel := i32(target) - i32(relocation.offset)
|
||||
if rel & 3 != 0 {
|
||||
append(errors, Error{inst_idx = u32(relocation.inst_idx), code = .LABEL_OUT_OF_RANGE})
|
||||
return true
|
||||
}
|
||||
rel >>= 2
|
||||
if rel < -(1<<18) || rel > (1<<18)-1 {
|
||||
append(errors, Error{inst_idx = u32(relocation.inst_idx), code = .LABEL_OUT_OF_RANGE})
|
||||
return true
|
||||
}
|
||||
word = (word &~ 0x7FFFF) | (u32(rel) & 0x7FFFF)
|
||||
|
||||
case .REL_PC18:
|
||||
// LDPC: relative to the instruction's address aligned down to 8, scaled
|
||||
// by 8, 18-bit signed.
|
||||
rel := i32(target) - (i32(relocation.offset) &~ i32(7))
|
||||
if rel & 7 != 0 {
|
||||
append(errors, Error{inst_idx = u32(relocation.inst_idx), code = .LABEL_OUT_OF_RANGE})
|
||||
return true
|
||||
}
|
||||
rel >>= 3
|
||||
if rel < -(1<<17) || rel > (1<<17)-1 {
|
||||
append(errors, Error{inst_idx = u32(relocation.inst_idx), code = .LABEL_OUT_OF_RANGE})
|
||||
return true
|
||||
}
|
||||
word = (word &~ 0x3FFFF) | (u32(rel) & 0x3FFFF)
|
||||
|
||||
case .J26:
|
||||
// J/JAL: target = ((PC+4)[31:28] << 28) | (encoded_field << 2)
|
||||
if target & 3 != 0 {
|
||||
|
||||
@@ -125,6 +125,8 @@ Operand_Type :: enum u8 {
|
||||
REL_J26, // 26-bit region jump (J / JAL)
|
||||
REL21, // R6 21-bit compact branch (BC1EQZ/NEZ)
|
||||
REL26, // R6 26-bit compact branch (BC/BALC)
|
||||
REL19, // R6 PC-relative load (LWPC/LWUPC, 19-bit << 2)
|
||||
REL18, // R6 PC-relative load (LDPC, 18-bit << 3)
|
||||
|
||||
// Memory: base GPR + 16-bit signed displacement
|
||||
MEM,
|
||||
@@ -164,6 +166,8 @@ Operand_Encoding :: enum u8 {
|
||||
BRANCH_16, // bits 15-0 as PC-relative word offset (delay-slot adjusted)
|
||||
BRANCH_21, // R6 compact branch: bits 20-0
|
||||
BRANCH_26, // R6 compact branch: bits 25-0
|
||||
BRANCH_19, // R6 PC-relative load: bits 18-0 (LWPC/LWUPC)
|
||||
BRANCH_18, // R6 PC-relative load: bits 17-0 (LDPC)
|
||||
|
||||
// FP condition code
|
||||
FCC_BC, // bits 20-18 (FP branches, MOVF/MOVT)
|
||||
|
||||
@@ -412,6 +412,12 @@ inst_lsa_r_r_r_i5 :: #force_inline proc "contextless" (dst: GPR, src: G
|
||||
emit_lsa_r_r_r_i5 :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: GPR, src: GPR, src2: GPR, imm: i64) { append(instructions, inst_lsa_r_r_r_i5(dst, src, src2, imm)) }
|
||||
inst_dlsa_r_r_r_i5 :: #force_inline proc "contextless" (dst: GPR, src: GPR, src2: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .DLSA, operand_count = 4, length = 4, ops = {op_gpr(dst), op_gpr(src), op_gpr(src2), op_imm(imm, 1)}} }
|
||||
emit_dlsa_r_r_r_i5 :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: GPR, src: GPR, src2: GPR, imm: i64) { append(instructions, inst_dlsa_r_r_r_i5(dst, src, src2, imm)) }
|
||||
inst_lwpc_r_rel :: #force_inline proc "contextless" (dst: GPR, target: u32) -> Instruction { return Instruction{mnemonic = .LWPC, operand_count = 2, length = 4, ops = {op_gpr(dst), op_label(target), {}, {}}} }
|
||||
emit_lwpc_r_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: GPR, target: u32) { append(instructions, inst_lwpc_r_rel(dst, target)) }
|
||||
inst_lwupc_r_rel :: #force_inline proc "contextless" (dst: GPR, target: u32) -> Instruction { return Instruction{mnemonic = .LWUPC, operand_count = 2, length = 4, ops = {op_gpr(dst), op_label(target), {}, {}}} }
|
||||
emit_lwupc_r_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: GPR, target: u32) { append(instructions, inst_lwupc_r_rel(dst, target)) }
|
||||
inst_ldpc_r_rel :: #force_inline proc "contextless" (dst: GPR, target: u32) -> Instruction { return Instruction{mnemonic = .LDPC, operand_count = 2, length = 4, ops = {op_gpr(dst), op_label(target), {}, {}}} }
|
||||
emit_ldpc_r_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: GPR, target: u32) { append(instructions, inst_ldpc_r_rel(dst, target)) }
|
||||
inst_seleqz_r_r_r :: #force_inline proc "contextless" (dst: GPR, src: GPR, src2: GPR) -> Instruction { return Instruction{mnemonic = .SELEQZ, operand_count = 3, length = 4, ops = {op_gpr(dst), op_gpr(src), op_gpr(src2), {}}} }
|
||||
emit_seleqz_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, dst: GPR, src: GPR, src2: GPR) { append(instructions, inst_seleqz_r_r_r(dst, src, src2)) }
|
||||
inst_selnez_r_r_r :: #force_inline proc "contextless" (dst: GPR, src: GPR, src2: GPR) -> Instruction { return Instruction{mnemonic = .SELNEZ, operand_count = 3, length = 4, ops = {op_gpr(dst), op_gpr(src), op_gpr(src2), {}}} }
|
||||
@@ -2427,6 +2433,12 @@ inst_lsa :: inst_lsa_r_r_r_i5
|
||||
emit_lsa :: emit_lsa_r_r_r_i5
|
||||
inst_dlsa :: inst_dlsa_r_r_r_i5
|
||||
emit_dlsa :: emit_dlsa_r_r_r_i5
|
||||
inst_lwpc :: inst_lwpc_r_rel
|
||||
emit_lwpc :: emit_lwpc_r_rel
|
||||
inst_lwupc :: inst_lwupc_r_rel
|
||||
emit_lwupc :: emit_lwupc_r_rel
|
||||
inst_ldpc :: inst_ldpc_r_rel
|
||||
emit_ldpc :: emit_ldpc_r_rel
|
||||
inst_seleqz :: inst_seleqz_r_r_r
|
||||
emit_seleqz :: emit_seleqz_r_r_r
|
||||
inst_selnez :: inst_selnez_r_r_r
|
||||
|
||||
@@ -17,6 +17,8 @@ Relocation_Type :: enum u8 {
|
||||
REL16, // 16-bit signed PC-rel branch offset (BEQ/BNE/BLEZ/BGTZ/...)
|
||||
REL21, // 21-bit signed PC-rel compact branch (R6 BEQZC/BNEZC)
|
||||
REL26, // 26-bit signed PC-rel compact branch (R6 BC/BALC)
|
||||
REL_PC19, // 19-bit R6 PC-relative load offset ((target - PC) >> 2) (LWPC/LWUPC)
|
||||
REL_PC18, // 18-bit R6 PC-relative load offset ((target - (PC & ~7)) >> 3) (LDPC)
|
||||
J26, // 26-bit J-type region target ((target_addr >> 2) & 0x3FFFFFF)
|
||||
HI16, // upper 16 of 32-bit absolute (LUI rt, %hi(sym)+0x8000 if LO16 paired)
|
||||
LO16, // lower 16 of 32-bit absolute (ADDIU rt, rt, %lo(sym))
|
||||
|
||||
@@ -1680,5 +1680,8 @@ ENCODING_TABLE := #partial [Mnemonic][]Encoding{
|
||||
.BNZ_W = { {.BNZ_W, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47C00000, 0xFFE00000, .MSA, {}} },
|
||||
.BNZ_D = { {.BNZ_D, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x47E00000, 0xFFE00000, .MSA, {}} },
|
||||
.BNZ_V = { {.BNZ_V, {.MSA_VEC,.REL16,.NONE,.NONE}, {.WT,.BRANCH_16,.NONE,.NONE}, 0x45E00000, 0xFFE00000, .MSA, {}} },
|
||||
.LWPC = { {.LWPC, {.GPR,.REL19,.NONE,.NONE}, {.RS,.BRANCH_19,.NONE,.NONE}, 0xEC080000, 0xFC180000, .MIPS32_R6, {}} },
|
||||
.LWUPC = { {.LWUPC, {.GPR,.REL19,.NONE,.NONE}, {.RS,.BRANCH_19,.NONE,.NONE}, 0xEC100000, 0xFC180000, .MIPS64_R6, {}} },
|
||||
.LDPC = { {.LDPC, {.GPR,.REL18,.NONE,.NONE}, {.RS,.BRANCH_18,.NONE,.NONE}, 0xEC180000, 0xFC1C0000, .MIPS64_R6, {}} },
|
||||
// SPECGEN:END
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ package rexcode_mips_generated
|
||||
import lib "../.."
|
||||
|
||||
@(rodata)
|
||||
DECODE_ENTRIES := [1005]lib.Decode_Entry{
|
||||
DECODE_ENTRIES := [1008]lib.Decode_Entry{
|
||||
{ .NOP, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x00000000, 0xFFFFFFFF, .MIPS_I, {} },
|
||||
{ .SSNOP, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x00000040, 0xFFFFFFFF, .MIPS32_R1, {} },
|
||||
{ .EHB, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x000000C0, 0xFFFFFFFF, .MIPS32_R2, {} },
|
||||
@@ -975,6 +975,9 @@ DECODE_ENTRIES := [1005]lib.Decode_Entry{
|
||||
{ .SV_S, {.VFPU_S,.MEM,.NONE,.NONE}, {.VFPU_VT_MEM,.VFPU_OFFSET_BASE,.NONE,.NONE}, 0xE8000000, 0xFC000000, .VFPU_PSP, {} },
|
||||
{ .AUIPC, {.GPR,.IMM16S,.NONE,.NONE}, {.RS,.IMM_16,.NONE,.NONE}, 0xEC1E0000, 0xFC1F0000, .MIPS32_R6, {} },
|
||||
{ .ALUIPC, {.GPR,.IMM16S,.NONE,.NONE}, {.RS,.IMM_16,.NONE,.NONE}, 0xEC1F0000, 0xFC1F0000, .MIPS32_R6, {} },
|
||||
{ .LDPC, {.GPR,.REL18,.NONE,.NONE}, {.RS,.BRANCH_18,.NONE,.NONE}, 0xEC180000, 0xFC1C0000, .MIPS64_R6, {} },
|
||||
{ .LWPC, {.GPR,.REL19,.NONE,.NONE}, {.RS,.BRANCH_19,.NONE,.NONE}, 0xEC080000, 0xFC180000, .MIPS32_R6, {} },
|
||||
{ .LWUPC, {.GPR,.REL19,.NONE,.NONE}, {.RS,.BRANCH_19,.NONE,.NONE}, 0xEC100000, 0xFC180000, .MIPS64_R6, {} },
|
||||
{ .VMIDT_P, {.VFPU_M_P,.NONE,.NONE,.NONE}, {.VFPU_VD,.NONE,.NONE,.NONE}, 0xF3830080, 0xFFFFFF80, .VFPU_PSP, {} },
|
||||
{ .VMIDT_T, {.VFPU_M_T,.NONE,.NONE,.NONE}, {.VFPU_VD,.NONE,.NONE,.NONE}, 0xF3838000, 0xFFFFFF80, .VFPU_PSP, {} },
|
||||
{ .VMIDT_Q, {.VFPU_M_Q,.NONE,.NONE,.NONE}, {.VFPU_VD,.NONE,.NONE,.NONE}, 0xF3838080, 0xFFFFFF80, .VFPU_PSP, {} },
|
||||
@@ -1077,11 +1080,11 @@ DECODE_INDEX_PRIMARY := [64]lib.Decode_Index{
|
||||
0x38 = { 959, 1},
|
||||
0x39 = { 960, 1},
|
||||
0x3A = { 961, 3},
|
||||
0x3B = { 964, 2},
|
||||
0x3C = { 966, 27},
|
||||
0x3D = { 993, 3},
|
||||
0x3E = { 996, 5},
|
||||
0x3F = {1001, 4},
|
||||
0x3B = { 964, 5},
|
||||
0x3C = { 969, 27},
|
||||
0x3D = { 996, 3},
|
||||
0x3E = { 999, 5},
|
||||
0x3F = {1004, 4},
|
||||
}
|
||||
|
||||
@(rodata)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -350,27 +350,23 @@ end
|
||||
|
||||
-- ---- Branches: derive bits/regs, then mark the PC-relative offset variable.
|
||||
-- Compact (R6) branches need the r6 ISA, so each family passes its own mattr.
|
||||
local function bword(line, mattr)
|
||||
local p = io.popen(string.format("printf '%%s\\n' '%s' | llvm-mc --assemble --triple=mips --mattr=%s --show-encoding 2>/dev/null", line, mattr))
|
||||
local out = p:read("*a"); p:close()
|
||||
local b1,b2,b3,b4 = out:match("0x(%x%x),0x(%x%x),0x(%x%x),0x(%x%x)")
|
||||
if not b1 then return nil end
|
||||
return tonumber(b1..b2..b3..b4, 16)
|
||||
end
|
||||
local function branch_block(mnem, ops, enc, feat, asm, maxes, offbits, mattr)
|
||||
local function branch_block(mnem, ops, enc, feat, asm, maxes, offbits, cmd)
|
||||
local zero={}; for i=1,#maxes do zero[i]=0 end
|
||||
local b0 = bword(asm(zero), mattr)
|
||||
local b0 = word(asm(zero), cmd)
|
||||
if not b0 then skips[#skips+1]=mnem; return end
|
||||
local vs={}
|
||||
for i=1,#maxes do
|
||||
local v={}; for j=1,#maxes do v[j]=0 end; v[i]=maxes[i]
|
||||
local w=bword(asm(v), mattr); if not w then skips[#skips+1]=mnem; return end; vs[#vs+1]=w
|
||||
local w=word(asm(v), cmd); if not w then skips[#skips+1]=mnem; return end; vs[#vs+1]=w
|
||||
end
|
||||
local m = bit.band(mask_of(b0,vs), bit.bnot((2^offbits)-1)) -- offset field = variable
|
||||
n_forms=n_forms+1
|
||||
sections[#sections+1]=string.format(" .%s = { {.%s, %s, %s, 0x%s, 0x%s, .%s, {}} },",
|
||||
mnem, mnem, ops, enc, bit.tohex(b0):upper(), bit.tohex(m):upper(), feat)
|
||||
end
|
||||
local LLVM_MSA = "llvm-mc --assemble --triple=mips --mattr=+msa --show-encoding"
|
||||
local LLVM_R6 = "llvm-mc --assemble --triple=mips --mattr=+mips32r6 --show-encoding"
|
||||
local LLVM_64R6 = "llvm-mc --assemble --triple=mips64 --mattr=+mips64r6 --show-encoding"
|
||||
|
||||
-- NOTE: the R6 two-/one-register compact branches (BEQC/BNEC/BLTC/BGEC/BLTUC/
|
||||
-- BGEUC/BLEZC/BGTZC/BGEZC/BLTZC) are intentionally NOT generated here. They
|
||||
@@ -381,10 +377,18 @@ end
|
||||
for _, b in ipairs({{"BZ","bz"},{"BNZ","bnz"}}) do
|
||||
for _, d in ipairs({{"B","b"},{"H","h"},{"W","w"},{"D","d"},{"V","v"}}) do
|
||||
branch_block(b[1].."_"..d[1], "{.MSA_VEC,.REL16,.NONE,.NONE}", "{.WT,.BRANCH_16,.NONE,.NONE}", "MSA",
|
||||
function(v) return string.format("%s.%s $w%d,0", b[2], d[2], v[1]) end, {31}, 16, "+msa")
|
||||
function(v) return string.format("%s.%s $w%d,0", b[2], d[2], v[1]) end, {31}, 16, LLVM_MSA)
|
||||
end
|
||||
end
|
||||
|
||||
-- ---- R6 PC-relative loads (offset is a 19-/18-bit PC-relative label) --------
|
||||
branch_block("LWPC", "{.GPR,.REL19,.NONE,.NONE}", "{.RS,.BRANCH_19,.NONE,.NONE}", "MIPS32_R6",
|
||||
function(v) return string.format("lwpc $%d,0", v[1]) end, {31}, 19, LLVM_R6)
|
||||
branch_block("LWUPC", "{.GPR,.REL19,.NONE,.NONE}", "{.RS,.BRANCH_19,.NONE,.NONE}", "MIPS64_R6",
|
||||
function(v) return string.format("lwupc $%d,0", v[1]) end, {31}, 19, LLVM_64R6)
|
||||
branch_block("LDPC", "{.GPR,.REL18,.NONE,.NONE}", "{.RS,.BRANCH_18,.NONE,.NONE}", "MIPS64_R6",
|
||||
function(v) return string.format("ldpc $%d,0", v[1]) end, {31}, 18, LLVM_64R6)
|
||||
|
||||
-- ---- splice into the SoT ---------------------------------------------------
|
||||
local region = " // SPECGEN:BEGIN\n" .. table.concat(sections, "\n") .. "\n // SPECGEN:END"
|
||||
local fh = assert(io.open(TABLE, "r")); local src = fh:read("*a"); fh:close()
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -277,7 +277,7 @@ can_generate_operand :: proc(op: mips.Operand_Type) -> bool {
|
||||
return true
|
||||
case .IMM5, .IMM16S, .IMM16U, .IMM20, .SEL, .FCC:
|
||||
return true
|
||||
case .REL16, .REL21, .REL26, .REL_J26:
|
||||
case .REL16, .REL21, .REL26, .REL_J26, .REL19, .REL18:
|
||||
return true
|
||||
case .MEM:
|
||||
return true
|
||||
@@ -313,7 +313,7 @@ operand_suffix :: proc(op: mips.Operand_Type) -> string {
|
||||
case .IMM20: return "i20"
|
||||
case .SEL: return "sel"
|
||||
case .FCC: return "cc"
|
||||
case .REL16: return "rel"
|
||||
case .REL16, .REL19, .REL18: return "rel"
|
||||
case .REL21: return "rel21"
|
||||
case .REL26: return "rel26"
|
||||
case .REL_J26: return "j"
|
||||
@@ -338,7 +338,7 @@ operand_param_type :: proc(op: mips.Operand_Type) -> string {
|
||||
return "Register"
|
||||
case .IMM5, .IMM16S, .IMM16U, .IMM20, .SEL, .FCC:
|
||||
return "i64"
|
||||
case .REL16, .REL21, .REL26, .REL_J26:
|
||||
case .REL16, .REL21, .REL26, .REL_J26, .REL19, .REL18:
|
||||
return "u32"
|
||||
case .MEM: return "Memory"
|
||||
}
|
||||
@@ -377,7 +377,7 @@ write_op_expr :: proc(sb: ^strings.Builder, op: mips.Operand_Type, name: string)
|
||||
fmt.sbprintf(sb, "op_reg(%s)", name)
|
||||
case .IMM5, .IMM16S, .IMM16U, .IMM20, .SEL, .FCC:
|
||||
fmt.sbprintf(sb, "op_imm(%s, %d)", name, operand_imm_size(op))
|
||||
case .REL16, .REL21, .REL26, .REL_J26:
|
||||
case .REL16, .REL21, .REL26, .REL_J26, .REL19, .REL18:
|
||||
fmt.sbprintf(sb, "op_label(%s)", name)
|
||||
case .MEM:
|
||||
fmt.sbprintf(sb, "op_mem(%s, 4)", name)
|
||||
@@ -403,7 +403,7 @@ param_names :: proc(sig: Operand_Signature) -> [4]string {
|
||||
case .IMM5, .IMM16S, .IMM16U, .IMM20, .SEL, .FCC:
|
||||
result[i] = imm_n == 0 ? "imm" : fmt.tprintf("imm%d", imm_n + 1)
|
||||
imm_n += 1
|
||||
case .REL16, .REL21, .REL26, .REL_J26:
|
||||
case .REL16, .REL21, .REL26, .REL_J26, .REL19, .REL18:
|
||||
result[i] = rel_n == 0 ? "target" : fmt.tprintf("target%d", rel_n + 1)
|
||||
rel_n += 1
|
||||
case .MEM:
|
||||
|
||||
Reference in New Issue
Block a user