From 4944213790e4b55ce20f1513b33d2906b1f3700f Mon Sep 17 00:00:00 2001 From: Dylan Reimerink Date: Wed, 1 Nov 2023 08:50:36 +0100 Subject: [PATCH] asm: Add LoadMemSX instruction ISAv4 adds a new instruction to load a memory value and sign extend it. To do so a new mode is used. This commit adds a new function to emit this instruction and adds the logic to print it nicely. Signed-off-by: Dylan Reimerink --- asm/instruction.go | 2 +- asm/load_store.go | 21 +++++++++++++++++++++ asm/load_store_string.go | 12 ++++++++---- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/asm/instruction.go b/asm/instruction.go index b8db6cb77..f1b0a186b 100644 --- a/asm/instruction.go +++ b/asm/instruction.go @@ -308,7 +308,7 @@ func (ins Instruction) Format(f fmt.State, c rune) { fmt.Fprintf(f, "imm: %d", ins.Constant) case IndMode: fmt.Fprintf(f, "dst: %s src: %s imm: %d", ins.Dst, ins.Src, ins.Constant) - case MemMode: + case MemMode, MemSXMode: fmt.Fprintf(f, "dst: %s src: %s off: %d imm: %d", ins.Dst, ins.Src, ins.Offset, ins.Constant) case XAddMode: fmt.Fprintf(f, "dst: %s src: %s", ins.Dst, ins.Src) diff --git a/asm/load_store.go b/asm/load_store.go index 574ee377c..944db68c1 100644 --- a/asm/load_store.go +++ b/asm/load_store.go @@ -24,6 +24,8 @@ const ( IndMode Mode = 0x40 // MemMode - load from memory MemMode Mode = 0x60 + // MemSXMode - load from memory, sign extension + MemSXMode Mode = 0x80 // XAddMode - add atomically across processors. XAddMode Mode = 0xc0 ) @@ -73,6 +75,11 @@ func LoadMemOp(size Size) OpCode { return OpCode(LdXClass).SetMode(MemMode).SetSize(size) } +// LoadSXMemOp returns the OpCode to load a value of given size from memory sign extended. +func LoadSXMemOp(size Size) OpCode { + return OpCode(LdXClass).SetMode(MemSXMode).SetSize(size) +} + // LoadMem emits `dst = *(size *)(src + offset)`. func LoadMem(dst, src Register, offset int16, size Size) Instruction { return Instruction{ @@ -83,6 +90,20 @@ func LoadMem(dst, src Register, offset int16, size Size) Instruction { } } +// LoadMemSX emits `dst = *(size *)(src + offset)` but sign extends dst. +func LoadMemSX(dst, src Register, offset int16, size Size) Instruction { + if size == DWord { + return Instruction{OpCode: InvalidOpCode} + } + + return Instruction{ + OpCode: LoadSXMemOp(size), + Dst: dst, + Src: src, + Offset: offset, + } +} + // LoadImmOp returns the OpCode to load an immediate of given size. // // As of kernel 4.20, only DWord size is accepted. diff --git a/asm/load_store_string.go b/asm/load_store_string.go index 76d29a075..c48080327 100644 --- a/asm/load_store_string.go +++ b/asm/load_store_string.go @@ -13,6 +13,7 @@ func _() { _ = x[AbsMode-32] _ = x[IndMode-64] _ = x[MemMode-96] + _ = x[MemSXMode-128] _ = x[XAddMode-192] } @@ -21,8 +22,9 @@ const ( _Mode_name_1 = "AbsMode" _Mode_name_2 = "IndMode" _Mode_name_3 = "MemMode" - _Mode_name_4 = "XAddMode" - _Mode_name_5 = "InvalidMode" + _Mode_name_4 = "MemSXMode" + _Mode_name_5 = "XAddMode" + _Mode_name_6 = "InvalidMode" ) func (i Mode) String() string { @@ -35,10 +37,12 @@ func (i Mode) String() string { return _Mode_name_2 case i == 96: return _Mode_name_3 - case i == 192: + case i == 128: return _Mode_name_4 - case i == 255: + case i == 192: return _Mode_name_5 + case i == 255: + return _Mode_name_6 default: return "Mode(" + strconv.FormatInt(int64(i), 10) + ")" }