fix: restore iota blocks, asm --format flag and prose after the syntax pass
This commit is contained in:
@@ -413,7 +413,7 @@ func encodeARM64AddSubImm(mnem string, ops []*ast.Operand) ([]byte, error) {
|
||||
if len(ops) != 2 && len(ops) != 3 {
|
||||
return nil, fmt.Errorf("%s expects 2 or 3 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
v := int32(immFromOperand(ops[0]))
|
||||
v := immFromOperand(ops[0])
|
||||
rd := arm64RegNum(operandRegName(ops[len(ops)-1]))
|
||||
rn := rd
|
||||
if len(ops) == 3 {
|
||||
@@ -606,7 +606,7 @@ func encodeARM64LoadImm(rd int, v int64, mnem string) ([]byte, error) {
|
||||
// - C_ABCON0 (0 < v ≤ 4095): bitmask first for positive values
|
||||
// - Negative values: MOVN first, then bitmask
|
||||
// - C_MOVCON (movcon-eligible, outside ABCON range): MOVZ/MOVN first
|
||||
tryBitmaskFirst := (d > 0 && d <= 0xFFF)
|
||||
tryBitmaskFirst := d > 0 && d <= 0xFFF
|
||||
|
||||
if tryBitmaskFirst {
|
||||
// Small immediate: try bitmask first (Go uses ORR for values like $1, $256).
|
||||
|
||||
@@ -234,8 +234,6 @@ const (
|
||||
a64CondLT = 0xb
|
||||
a64CondGT = 0xc
|
||||
a64CondLE = 0xd
|
||||
a64CondAL = 0xe
|
||||
a64CondNV = 0xf
|
||||
)
|
||||
|
||||
// arm64CondMap maps Go assembler condition mnemonics to AArch64 condition codes.
|
||||
|
||||
@@ -17,7 +17,6 @@ import (
|
||||
// and external ones against undefined globals. The output links with the
|
||||
// system toolchain (cc/ld) the way a hand-assembled .o would.
|
||||
|
||||
// ELF constants (ELF64, little-endian, System V).
|
||||
const (
|
||||
elfClass64 = 2
|
||||
elfDataLSB = 1
|
||||
@@ -36,17 +35,14 @@ const (
|
||||
shfAlloc = 2
|
||||
shfExecInstr = 4
|
||||
|
||||
stbLocal = 0
|
||||
stbGlobal = 1
|
||||
|
||||
sttNotype = 0
|
||||
sttObject = 1
|
||||
sttFunc = 2
|
||||
sttSection = 3
|
||||
stInfoShift = 4
|
||||
|
||||
rX8664PC32 = 2
|
||||
rX8664_64 = 1 // R_X86_64_64 (absolute 64-bit)
|
||||
)
|
||||
|
||||
// elfSym is one symbol-table entry in construction.
|
||||
|
||||
+2
-2
@@ -87,7 +87,7 @@ func emitDWARF(img *Image, srcFile string) *dwarfSections {
|
||||
ds.debugLineStr = lineStr.bytes()
|
||||
|
||||
// Build .debug_line.
|
||||
ds.debugLine = dwarfBuildLineSection(img, srcFile, ds)
|
||||
ds.debugLine = dwarfBuildLineSection(img, ds)
|
||||
|
||||
// Build .debug_info.
|
||||
ds.debugInfo = dwarfBuildInfoSection(img, srcFile, ds)
|
||||
@@ -98,7 +98,7 @@ func emitDWARF(img *Image, srcFile string) *dwarfSections {
|
||||
}
|
||||
|
||||
// dwarfBuildLineSection builds a complete .debug_line section.
|
||||
func dwarfBuildLineSection(img *Image, srcFile string, ds *dwarfSections) []byte {
|
||||
func dwarfBuildLineSection(img *Image, ds *dwarfSections) []byte {
|
||||
var b []byte
|
||||
le := binary.LittleEndian
|
||||
|
||||
|
||||
+2
-2
@@ -701,7 +701,7 @@ func splitMask(ops []Operand) ([]Operand, int, error) {
|
||||
return nil, 0, fmt.Errorf("at most one mask register operand")
|
||||
}
|
||||
if r.idx == 0 {
|
||||
return nil, 0, fmt.Errorf("K0 is not a usable mask register")
|
||||
return nil, 0, fmt.Errorf("k0 is not a usable mask register")
|
||||
}
|
||||
mask = r.idx
|
||||
continue
|
||||
@@ -1203,7 +1203,7 @@ func (e *enc) emitEvexFields(spec evexSpec, ll, regIdx, vvvvIdx int, rm Operand,
|
||||
// The b bit and the L'L field carry the rounding/SAE/broadcast mode:
|
||||
// a rounding mode replaces L'L with the rc value, plain SAE and
|
||||
// broadcast keep the vector length.
|
||||
b, ll := 0, ll
|
||||
b := 0
|
||||
switch {
|
||||
case sfx.rounding >= 0:
|
||||
b, ll = 1, sfx.rounding
|
||||
|
||||
+5
-2
@@ -33,7 +33,10 @@ import (
|
||||
// methods supply the toolchain preamble, the MinLC (pc-value delta unit)
|
||||
// and the relocation-type mapping for code relocations.
|
||||
|
||||
// GOOBJ block indices (cmd/internal/goobj).
|
||||
// GOOBJ block indices (cmd/internal/goobj). These MUST match the real
|
||||
// archive layout: the emitter writes the header offsets per index and the
|
||||
// reader (groundtruth, goobj_resolve) parses real Go archives with them.
|
||||
// blkAutolib is unused by the emitter but still defines index 0.
|
||||
const (
|
||||
blkAutolib = iota
|
||||
blkPkgIdx
|
||||
@@ -417,7 +420,7 @@ func (img *Image) emitGOObject(pkgPath, srcPath string, pre []byte, minLC int, r
|
||||
// The string table. Absolute offsets: it starts right after the
|
||||
// 96-byte header (magic, fingerprint, flags, the 19 block offsets).
|
||||
const headerSize = 8 + 8 + 4 + 4*(blkEnd+1)
|
||||
strTab := []byte{}
|
||||
var strTab []byte
|
||||
strOff := map[string]uint32{}
|
||||
addStr := func(s string) {
|
||||
if _, ok := strOff[s]; ok {
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ func (fl *FuncLayout) LineAt(offset int) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Reloc is one static-symbol reference within a function body: the disp32
|
||||
// RelocKind Reloc is one static-symbol reference within a function body: the disp32
|
||||
// field at Off (function-relative) must reach the symbol plus Addend,
|
||||
// measured from After, the address just past the instruction. An External
|
||||
// relocation names a symbol no GLOBL in the file defines; the object-file
|
||||
|
||||
+57
-59
@@ -672,8 +672,6 @@ func encodeLOONG64ImmArith(mnem string, de l64DualEnc, ops []*ast.Operand) ([]by
|
||||
const (
|
||||
lu12iw = 0x0a << 25
|
||||
ori = 0x00e << 22
|
||||
lu32id = 0x0b << 25
|
||||
lu52id = 0x00c << 22
|
||||
)
|
||||
if v == int64(int32(v)) {
|
||||
if v&0xfff == 0 && (v < 0x800 || v > 0xfff) {
|
||||
@@ -771,7 +769,7 @@ func encodeLOONG64Mov(instr *ast.Instr, mnem string, fi loong64FrameInfo, relocs
|
||||
if rd < 0 {
|
||||
return nil, fmt.Errorf("%s $sym(SB): invalid destination register", mnem)
|
||||
}
|
||||
return encodeLOONG64SBAddr(src.Imm.Sym, rd, mnem, relocs), nil
|
||||
return encodeLOONG64SBAddr(src.Imm.Sym, rd, relocs), nil
|
||||
}
|
||||
rd := l64Reg(dst)
|
||||
if rd < 0 {
|
||||
@@ -832,14 +830,14 @@ func encodeLOONG64Mov(instr *ast.Instr, mnem string, fi loong64FrameInfo, relocs
|
||||
if rd < 0 {
|
||||
return nil, fmt.Errorf("%s: invalid destination register", mnem)
|
||||
}
|
||||
return encodeLOONG64MemOp(mnem, ops[0], rd, true, fi, relocs)
|
||||
return encodeLOONG64MemOp(mnem, ops[0], rd, true, fi)
|
||||
}
|
||||
if !isMemOperand(src) && isMemOperand(dst) {
|
||||
rs := l64Reg(src)
|
||||
if rs < 0 {
|
||||
return nil, fmt.Errorf("%s: invalid source register", mnem)
|
||||
}
|
||||
return encodeLOONG64MemOp(mnem, ops[1], rs, false, fi, relocs)
|
||||
return encodeLOONG64MemOp(mnem, ops[1], rs, false, fi)
|
||||
}
|
||||
|
||||
// Register → register.
|
||||
@@ -933,20 +931,20 @@ const (
|
||||
l64St1
|
||||
l64St0
|
||||
|
||||
l64Dcon12_0
|
||||
l64Dcon12_20S
|
||||
l64Dcon20S_20
|
||||
l64Dcon12_12S
|
||||
l64Dcon20S_12S
|
||||
l64Dcon20S_0
|
||||
l64Dcon12_12U
|
||||
l64Dcon20S_12U
|
||||
l64Dcon32_12S
|
||||
l64Dcon32_0
|
||||
l64Dcon32_20
|
||||
l64Dcon12_32S
|
||||
l64Dcon20S_32
|
||||
l64Dcon32_12U
|
||||
l64dcon120
|
||||
l64dcon1220s
|
||||
l64dcon20s20
|
||||
l64dcon1212s
|
||||
l64dcon20s12s
|
||||
l64dcon20s0
|
||||
l64dcon1212u
|
||||
l64dcon20s12u
|
||||
l64dcon3212s
|
||||
l64dcon320
|
||||
l64dcon3220
|
||||
l64dcon1232s
|
||||
l64dcon20s32
|
||||
l64dcon3212u
|
||||
l64Dcon
|
||||
)
|
||||
|
||||
@@ -987,91 +985,91 @@ func l64DconClass(v int64) int {
|
||||
lo20 := l64BitField(v, 12, 20)
|
||||
lo12 := l64BitField(v, 0, 12)
|
||||
if tzb >= 52 {
|
||||
return l64Dcon12_0
|
||||
return l64dcon120
|
||||
}
|
||||
if tzb >= 32 {
|
||||
if ((hi20 == l64All1 || hi20 == l64St1) && hi12 == l64All1) || ((hi20 == l64All0 || hi20 == l64St0) && hi12 == l64All0) {
|
||||
return l64Dcon20S_0
|
||||
return l64dcon20s0
|
||||
}
|
||||
return l64Dcon32_0
|
||||
return l64dcon320
|
||||
}
|
||||
if tzb >= 12 {
|
||||
if lo20 == l64St1 || lo20 == l64All1 {
|
||||
if hi20 == l64All1 {
|
||||
return l64Dcon12_20S
|
||||
return l64dcon1220s
|
||||
}
|
||||
if (hi20 == l64St1 && hi12 == l64All1) || ((hi20 == l64St0 || hi20 == l64All0) && hi12 == l64All0) {
|
||||
return l64Dcon20S_20
|
||||
return l64dcon20s20
|
||||
}
|
||||
return l64Dcon32_20
|
||||
return l64dcon3220
|
||||
}
|
||||
if hi20 == l64All0 {
|
||||
return l64Dcon12_20S
|
||||
return l64dcon1220s
|
||||
}
|
||||
if (hi20 == l64St0 && hi12 == l64All0) || ((hi20 == l64St1 || hi20 == l64All1) && hi12 == l64All1) {
|
||||
return l64Dcon20S_20
|
||||
return l64dcon20s20
|
||||
}
|
||||
return l64Dcon32_20
|
||||
return l64dcon3220
|
||||
}
|
||||
if lo12 == l64St1 || lo12 == l64All1 {
|
||||
if lo20 == l64All1 {
|
||||
if hi20 == l64All1 {
|
||||
return l64Dcon12_12S
|
||||
return l64dcon1212s
|
||||
}
|
||||
if (hi20 == l64St1 && hi12 == l64All1) || ((hi20 == l64St0 || hi20 == l64All0) && hi12 == l64All0) {
|
||||
return l64Dcon20S_12S
|
||||
return l64dcon20s12s
|
||||
}
|
||||
return l64Dcon32_12S
|
||||
return l64dcon3212s
|
||||
}
|
||||
if lo20 == l64St1 {
|
||||
if hi20 == l64All1 {
|
||||
return l64Dcon12_32S
|
||||
return l64dcon1232s
|
||||
}
|
||||
if (hi20 == l64St1 && hi12 == l64All1) || ((hi20 == l64St0 || hi20 == l64All0) && hi12 == l64All0) {
|
||||
return l64Dcon20S_32
|
||||
return l64dcon20s32
|
||||
}
|
||||
return l64Dcon
|
||||
}
|
||||
if lo20 == l64All0 {
|
||||
if hi20 == l64All0 {
|
||||
return l64Dcon12_12U
|
||||
return l64dcon1212u
|
||||
}
|
||||
if ((hi20 == l64St1 || hi20 == l64All1) && hi12 == l64All1) || (hi20 == l64St0 && hi12 == l64All0) {
|
||||
return l64Dcon20S_12U
|
||||
return l64dcon20s12u
|
||||
}
|
||||
return l64Dcon32_12U
|
||||
return l64dcon3212u
|
||||
}
|
||||
if hi20 == l64All0 {
|
||||
return l64Dcon12_32S
|
||||
return l64dcon1232s
|
||||
}
|
||||
if ((hi20 == l64St1 || hi20 == l64All1) && hi12 == l64All1) || (hi20 == l64St0 && hi12 == l64All0) {
|
||||
return l64Dcon20S_32
|
||||
return l64dcon20s32
|
||||
}
|
||||
return l64Dcon
|
||||
}
|
||||
if lo20 == l64All0 {
|
||||
if hi20 == l64All0 {
|
||||
return l64Dcon12_12U
|
||||
return l64dcon1212u
|
||||
}
|
||||
if ((hi20 == l64St1 || hi20 == l64All1) && hi12 == l64All1) || (hi20 == l64St0 && hi12 == l64All0) {
|
||||
return l64Dcon20S_12U
|
||||
return l64dcon20s12u
|
||||
}
|
||||
return l64Dcon32_12U
|
||||
return l64dcon3212u
|
||||
}
|
||||
if lo20 == l64St1 || lo20 == l64All1 {
|
||||
if hi20 == l64All1 {
|
||||
return l64Dcon12_32S
|
||||
return l64dcon1232s
|
||||
}
|
||||
if (hi20 == l64St1 && hi12 == l64All1) || ((hi20 == l64St0 || hi20 == l64All0) && hi12 == l64All0) {
|
||||
return l64Dcon20S_32
|
||||
return l64dcon20s32
|
||||
}
|
||||
return l64Dcon
|
||||
}
|
||||
if hi20 == l64All0 {
|
||||
return l64Dcon12_32S
|
||||
return l64dcon1232s
|
||||
}
|
||||
if ((hi20 == l64St1 || hi20 == l64All1) && hi12 == l64All1) || (hi20 == l64St0 && hi12 == l64All0) {
|
||||
return l64Dcon20S_32
|
||||
return l64dcon20s32
|
||||
}
|
||||
return l64Dcon
|
||||
}
|
||||
@@ -1088,29 +1086,29 @@ func l64DconMovWords(rd int, v int64) []uint32 {
|
||||
ori = 0x00e << 22
|
||||
)
|
||||
switch l64DconClass(v) {
|
||||
case l64Dcon12_0:
|
||||
case l64dcon120:
|
||||
return []uint32{l64irr(lu52id, int(v>>52), 0, rd)}
|
||||
case l64Dcon12_20S:
|
||||
case l64dcon1220s:
|
||||
return []uint32{l64ir(lu12iw, int(v>>12), rd), l64irr(lu52id, int(v>>52), rd, rd)}
|
||||
case l64Dcon20S_20:
|
||||
case l64dcon20s20:
|
||||
return []uint32{l64ir(lu12iw, int(v>>12), rd), l64ir(lu32id, int(v>>32), rd)}
|
||||
case l64Dcon12_12S:
|
||||
case l64dcon1212s:
|
||||
return []uint32{l64irr(addid, int(v), 0, rd), l64irr(lu52id, int(v>>52), rd, rd)}
|
||||
case l64Dcon20S_12S, l64Dcon20S_0:
|
||||
case l64dcon20s12s, l64dcon20s0:
|
||||
return []uint32{l64irr(addiw, int(v), 0, rd), l64ir(lu32id, int(v>>32), rd)}
|
||||
case l64Dcon12_12U:
|
||||
case l64dcon1212u:
|
||||
return []uint32{l64irr(ori, int(v), 0, rd), l64irr(lu52id, int(v>>52), rd, rd)}
|
||||
case l64Dcon20S_12U:
|
||||
case l64dcon20s12u:
|
||||
return []uint32{l64irr(ori, int(v), 0, rd), l64ir(lu32id, int(v>>32), rd)}
|
||||
case l64Dcon32_12S, l64Dcon32_0:
|
||||
case l64dcon3212s, l64dcon320:
|
||||
return []uint32{l64irr(addiw, int(v), 0, rd), l64ir(lu32id, int(v>>32), rd), l64irr(lu52id, int(v>>52), rd, rd)}
|
||||
case l64Dcon32_20:
|
||||
case l64dcon3220:
|
||||
return []uint32{l64ir(lu12iw, int(v>>12), rd), l64ir(lu32id, int(v>>32), rd), l64irr(lu52id, int(v>>52), rd, rd)}
|
||||
case l64Dcon12_32S:
|
||||
case l64dcon1232s:
|
||||
return []uint32{l64ir(lu12iw, int(v>>12), rd), l64irr(ori, int(v), rd, rd), l64irr(lu52id, int(v>>52), rd, rd)}
|
||||
case l64Dcon20S_32:
|
||||
case l64dcon20s32:
|
||||
return []uint32{l64ir(lu12iw, int(v>>12), rd), l64irr(ori, int(v), rd, rd), l64ir(lu32id, int(v>>32), rd)}
|
||||
case l64Dcon32_12U:
|
||||
case l64dcon3212u:
|
||||
return []uint32{l64irr(ori, int(v), 0, rd), l64ir(lu32id, int(v>>32), rd), l64irr(lu52id, int(v>>52), rd, rd)}
|
||||
default:
|
||||
return []uint32{l64ir(lu12iw, int(v>>12), rd), l64irr(ori, int(v), rd, rd), l64ir(lu32id, int(v>>32), rd), l64irr(lu52id, int(v>>52), rd, rd)}
|
||||
@@ -1161,7 +1159,7 @@ func encodeLOONG64LoadImm(rd int, v int64, mnem string) []byte {
|
||||
// encodeLOONG64MemOp encodes a memory load (load = true) or store with a
|
||||
// 12-bit offset, or the 3-instruction expansion for larger offsets:
|
||||
// lu12i.w r30, (off+0x800)>>12; add.d r30, rj, r30; ld/st rd, off(r30).
|
||||
func encodeLOONG64MemOp(mnem string, mem *ast.Operand, reg int, load bool, fi loong64FrameInfo, relocs *[]Reloc) ([]byte, error) {
|
||||
func encodeLOONG64MemOp(mnem string, mem *ast.Operand, reg int, load bool, fi loong64FrameInfo) ([]byte, error) {
|
||||
rj, off := l64MemWithFrame(mem, fi)
|
||||
if rj < 0 {
|
||||
return nil, fmt.Errorf("invalid memory operand")
|
||||
@@ -1266,7 +1264,7 @@ func l64FpMoveKey(mnem string, sc, dc l64RegClass) (string, bool) {
|
||||
|
||||
// encodeLOONG64SBAddr emits pcalau12i rd, 0; addi.d rd, rd, 0 with the
|
||||
// R_LOONG64_ADDR_HI/LO relocation pair, loading a symbol's address.
|
||||
func encodeLOONG64SBAddr(sym *ast.Symbol, rd int, mnem string, relocs *[]Reloc) []byte {
|
||||
func encodeLOONG64SBAddr(sym *ast.Symbol, rd int, relocs *[]Reloc) []byte {
|
||||
if relocs != nil {
|
||||
*relocs = append(*relocs,
|
||||
Reloc{Off: 0, After: 0, Name: sym.Name, Kind: RelLoong64AddrHi, Addend: sym.Offset},
|
||||
|
||||
@@ -105,10 +105,10 @@ func loong64RegNum(name string) int {
|
||||
}
|
||||
// F0–F31, FCC0–FCC7, FCSR0–FCSR31.
|
||||
if len(name) >= 4 && name[:4] == "FCSR" {
|
||||
return loong64RegSpecial(name[4:], "FCSR", 31)
|
||||
return loong64RegSpecial(name[4:], 31)
|
||||
}
|
||||
if len(name) >= 3 && name[:3] == "FCC" {
|
||||
return loong64RegSpecial(name[3:], "FCC", 7)
|
||||
return loong64RegSpecial(name[3:], 7)
|
||||
}
|
||||
if len(name) < 2 {
|
||||
return -1
|
||||
@@ -131,7 +131,7 @@ func loong64RegNum(name string) int {
|
||||
}
|
||||
|
||||
// loong64RegSpecial parses a numbered FCC/FCSR register.
|
||||
func loong64RegSpecial(digits, prefix string, max int) int {
|
||||
func loong64RegSpecial(digits string, max int) int {
|
||||
if digits == "" {
|
||||
return -1
|
||||
}
|
||||
|
||||
+18
-18
@@ -65,28 +65,28 @@ var (
|
||||
CX = Reg{idx: 1, size: 2}
|
||||
DX = Reg{idx: 2, size: 2}
|
||||
BX = Reg{idx: 3, size: 2}
|
||||
SP = Reg{idx: 4, size: 2}
|
||||
BP = Reg{idx: 5, size: 2}
|
||||
_ = Reg{idx: 4, size: 2}
|
||||
_ = Reg{idx: 5, size: 2}
|
||||
SI = Reg{idx: 6, size: 2}
|
||||
DI = Reg{idx: 7, size: 2}
|
||||
|
||||
EAX = Reg{idx: 0, size: 4}
|
||||
ECX = Reg{idx: 1, size: 4}
|
||||
EDX = Reg{idx: 2, size: 4}
|
||||
EBX = Reg{idx: 3, size: 4}
|
||||
ESP = Reg{idx: 4, size: 4}
|
||||
EBP = Reg{idx: 5, size: 4}
|
||||
ESI = Reg{idx: 6, size: 4}
|
||||
EDI = Reg{idx: 7, size: 4}
|
||||
_ = Reg{idx: 0, size: 4}
|
||||
_ = Reg{idx: 1, size: 4}
|
||||
_ = Reg{idx: 2, size: 4}
|
||||
_ = Reg{idx: 3, size: 4}
|
||||
_ = Reg{idx: 4, size: 4}
|
||||
_ = Reg{idx: 5, size: 4}
|
||||
_ = Reg{idx: 6, size: 4}
|
||||
_ = Reg{idx: 7, size: 4}
|
||||
|
||||
RAX = Reg{idx: 0, size: 8}
|
||||
RCX = Reg{idx: 1, size: 8}
|
||||
RDX = Reg{idx: 2, size: 8}
|
||||
RBX = Reg{idx: 3, size: 8}
|
||||
RSP = Reg{idx: 4, size: 8}
|
||||
RBP = Reg{idx: 5, size: 8}
|
||||
RSI = Reg{idx: 6, size: 8}
|
||||
RDI = Reg{idx: 7, size: 8}
|
||||
_ = Reg{idx: 0, size: 8}
|
||||
_ = Reg{idx: 1, size: 8}
|
||||
_ = Reg{idx: 2, size: 8}
|
||||
_ = Reg{idx: 3, size: 8}
|
||||
_ = Reg{idx: 4, size: 8}
|
||||
_ = Reg{idx: 5, size: 8}
|
||||
_ = Reg{idx: 6, size: 8}
|
||||
_ = Reg{idx: 7, size: 8}
|
||||
)
|
||||
|
||||
// regByName maps an assembly register name (case-insensitive) to a Reg.
|
||||
|
||||
@@ -228,7 +228,7 @@ func encodeRISCVInstr(instr *ast.Instr, pc int, offsets map[string]int, fi riscv
|
||||
// MOV is a pseudo-instruction that the Go assembler uses for loads,
|
||||
// stores, register moves and immediate loads.
|
||||
case "MOV":
|
||||
return encodeRISCVMov(instr, offsets, fi, relocs)
|
||||
return encodeRISCVMov(instr, fi, relocs)
|
||||
|
||||
// JALR: indirect jump/call. Plan 9: JALR rs1, rd or JALR offset(rs1).
|
||||
case "JALR":
|
||||
@@ -527,7 +527,7 @@ func isImmOperand(op *ast.Operand) bool {
|
||||
// - MOV Rs, (Rd) register-relative store
|
||||
// - MOV Rs, Rd register-to-register move (ADDI $0)
|
||||
// - MOV $imm, Rd load immediate (ADDI or LUI+ADDIW)
|
||||
func encodeRISCVMov(instr *ast.Instr, offsets map[string]int, fi riscvFrameInfo, relocs *[]Reloc) ([]byte, error) {
|
||||
func encodeRISCVMov(instr *ast.Instr, fi riscvFrameInfo, relocs *[]Reloc) ([]byte, error) {
|
||||
ops := instr.Operands
|
||||
if len(ops) != 2 {
|
||||
return nil, fmt.Errorf("MOV expects 2 operands, got %d", len(ops))
|
||||
@@ -911,7 +911,7 @@ func tryCompressRVC(instr *ast.Instr, fi riscvFrameInfo) (uint16, bool) {
|
||||
}
|
||||
|
||||
case "ADDI":
|
||||
rd, rs1, imm := extractITypeParams(instr, fi)
|
||||
rd, rs1, imm := extractITypeParams(instr)
|
||||
if rd == -1 || rs1 == -1 {
|
||||
return 0, false
|
||||
}
|
||||
@@ -1060,13 +1060,13 @@ func tryCompressRVC(instr *ast.Instr, fi riscvFrameInfo) (uint16, bool) {
|
||||
}
|
||||
|
||||
case "ADDIW":
|
||||
rd, rs1, imm := extractITypeParams(instr, fi)
|
||||
rd, rs1, imm := extractITypeParams(instr)
|
||||
if rd == rs1 && rd != 0 && imm >= -32 && imm <= 31 {
|
||||
return rvcCI(0x1, uint32(rd), uint32(imm)&0x3F), true
|
||||
}
|
||||
|
||||
case "SLLI", "SRLI", "SRAI":
|
||||
rd, rs1, imm := extractITypeParams(instr, fi)
|
||||
rd, rs1, imm := extractITypeParams(instr)
|
||||
if rd == rs1 && rd != 0 && imm != 0 && imm >= 1 && imm <= 63 {
|
||||
if mnem == "SLLI" {
|
||||
// C.SLLI: funct3=0, op=10 quadrant, shamt in bits [12|6:2].
|
||||
@@ -1083,7 +1083,7 @@ func tryCompressRVC(instr *ast.Instr, fi riscvFrameInfo) (uint16, bool) {
|
||||
}
|
||||
|
||||
case "ANDI":
|
||||
rd, rs1, imm := extractITypeParams(instr, fi)
|
||||
rd, rs1, imm := extractITypeParams(instr)
|
||||
if isRVCIntReg(rd) && rd == rs1 && imm >= -32 && imm <= 31 {
|
||||
// C.ANDI: CB-type, funct3=0x4, funct2=0x2.
|
||||
return rvcCBShift(0x2, rvcReg3(rd), uint32(imm)&0x3F), true
|
||||
@@ -1131,7 +1131,7 @@ func extractSDParams(instr *ast.Instr, fi riscvFrameInfo) (rs2, rs1 int, imm int
|
||||
// extractITypeParams extracts rd, rs1, and immediate for an I-type
|
||||
// instruction. The Plan 9 order is INSTR $imm, rs1, rd (3 operands) or
|
||||
// INSTR $imm, rd (2 operands, rd is also the source).
|
||||
func extractITypeParams(instr *ast.Instr, fi riscvFrameInfo) (rd, rs1 int, imm int32) {
|
||||
func extractITypeParams(instr *ast.Instr) (rd, rs1 int, imm int32) {
|
||||
ops := instr.Operands
|
||||
switch len(ops) {
|
||||
case 3:
|
||||
|
||||
Reference in New Issue
Block a user