Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SOL] Add feature flag for disabling lddw #77

Merged
merged 2 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions llvm/lib/Target/SBF/Disassembler/SBFDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class SBFDisassembler : public MCDisassembler {
uint8_t getInstClass(uint64_t Inst) const { return (Inst >> 56) & 0x7; };
uint8_t getInstSize(uint64_t Inst) const { return (Inst >> 59) & 0x3; };
uint8_t getInstMode(uint64_t Inst) const { return (Inst >> 61) & 0x7; };
bool isMov32(uint64_t Inst) const { return (Inst >> 56) == 0xb4; }
};

} // end anonymous namespace
Expand Down Expand Up @@ -175,6 +176,10 @@ DecodeStatus SBFDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
STI.getFeatureBits()[SBF::ALU32])
Result = decodeInstruction(DecoderTableSBFALU3264, Instr, Insn, Address,
this, STI);
else if (isMov32(Insn) && !STI.getFeatureBits()[SBF::ALU32] &&
STI.getFeatureBits()[SBF::FeatureDisableLddw])
Result =
decodeInstruction(DecoderTableSBFv264, Instr, Insn, Address, this, STI);
else
Result =
decodeInstruction(DecoderTableSBF64, Instr, Insn, Address, this, STI);
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/Target/SBF/SBF.td
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ def FeatureDisableNeg : SubtargetFeature<"no-neg", "DisableNeg", "true",
def FeatureReverseSubImm : SubtargetFeature<"reverse-sub", "ReverseSubImm", "true",
"Reverse the operands in the 'sub reg, imm' instruction">;

def FeatureDisableLddw : SubtargetFeature<"no-lddw", "NoLddw", "true",
"Disable the lddw instruction">;

class Proc<string Name, list<SubtargetFeature> Features>
: Processor<Name, NoItineraries, Features>;

Expand All @@ -53,7 +56,7 @@ def : Proc<"v2", []>;
def : Proc<"v3", []>;
def : Proc<"probe", []>;
def : Proc<"sbfv2", [FeatureSolana, FeatureDynamicFrames, FeatureSdiv, FeatureRelocAbs64, FeatureStaticSyscalls,
FeatureDisableNeg, FeatureReverseSubImm]>;
FeatureDisableNeg, FeatureReverseSubImm, FeatureDisableLddw]>;

//===----------------------------------------------------------------------===//
// Assembly printer
Expand Down
28 changes: 16 additions & 12 deletions llvm/lib/Target/SBF/SBFInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ def SBFIsBigEndian : Predicate<"!CurDAG->getDataLayout().isLittleEndian()">;
def SBFHasALU32 : Predicate<"Subtarget->getHasAlu32()">;
def SBFNoALU32 : Predicate<"!Subtarget->getHasAlu32()">;
def SBFSubtargetSolana : Predicate<"Subtarget->isSolana()">;
def SBFHasLddw : Predicate<"!Subtarget->getNoLddw()">;
def SBFNoLddw : Predicate<"Subtarget->getNoLddw()">;

def SBFv2 : Predicate<"Subtarget->isSBFv2()">;
def NoSBFv2 : Predicate<"!Subtarget->isSBFv2()">;
def SBFHasNeg : Predicate<"!Subtarget->getDisableNeg()">;
Expand Down Expand Up @@ -322,13 +325,13 @@ let Constraints = "$dst = $src2" in {
defm XOR : ALU<SBF_XOR, "xor", xor>;
defm SRA : ALU<SBF_ARSH, "arsh", sra>;

let Predicates = [SBFv2] in {
let Predicates = [SBFNoLddw] in {
def HOR : ALU_RI<SBF_ALU64, SBF_HOR,
(outs GPR:$dst),
(ins GPR:$src2, i32imm:$imm),
"hor64 $dst, $imm",
[]>;
let DecoderNamespace = "AddrLoad" in {
let DecoderNamespace = "SBFv2" in {
def HOR_addr : ALU_RI<SBF_ALU64, SBF_HOR,
(outs GPR:$dst),
(ins GPR:$src2, u64imm:$imm),
Expand Down Expand Up @@ -405,7 +408,7 @@ class LD_IMM64<bits<4> Pseudo, string Mnemonic>
}

let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
def LD_imm64 : LD_IMM64<0, "lddw">, Requires<[NoSBFv2]>;
def LD_imm64 : LD_IMM64<0, "lddw">, Requires<[SBFHasLddw]>;
def MOV_rr : ALU_RR<SBF_ALU64, SBF_MOV,
(outs GPR:$dst),
(ins GPR:$src),
Expand Down Expand Up @@ -934,14 +937,15 @@ let isCodeGenOnly = 1 in {
def MOV_32_64 : ALU_RR<SBF_ALU, SBF_MOV,
(outs GPR:$dst), (ins GPR32:$src),
"mov32 $dst, $src", []>;
let Predicates = [SBFv2] in {
def MOV_32_64_imm : ALU_RI<SBF_ALU, SBF_MOV,
def MOV_32_64_addr : ALU_RI<SBF_ALU, SBF_MOV,
(outs GPR:$dst), (ins u64imm:$imm),
"mov32 $dst, $imm", []>, Requires<[SBFNoLddw]>;
}

let DecoderNamespace = "SBFv2", Predicates = [SBFNoLddw] in {
def MOV_32_64_imm : ALU_RI<SBF_ALU, SBF_MOV,
(outs GPR:$dst), (ins i32imm:$imm),
"mov32 $dst, $imm", []>;
def MOV_32_64_addr : ALU_RI<SBF_ALU, SBF_MOV,
(outs GPR:$dst), (ins u64imm:$imm),
"mov32 $dst, $imm", []>;
}
}

// In SBFv2, a CopyToReg of a 64-bit value is split in two instructions:
Expand All @@ -950,14 +954,14 @@ let isCodeGenOnly = 1 in {
// These instructions copy the value 0x1122334455667788 to a register.
def : Pat<(i64 imm:$imm),
(HOR (MOV_32_64_imm (i32 (Lower32 $imm))),
(i32 (Upper32 $imm)))>, Requires<[SBFv2]>;
(i32 (Upper32 $imm)))>, Requires<[SBFNoLddw]>;

// load 64-bit global address into register.
def : Pat<(SBFWrapper tglobaladdr:$in), (LD_imm64 tglobaladdr:$in)>,
Requires<[NoSBFv2]>;
Requires<[SBFHasLddw]>;
def : Pat<(SBFWrapper tglobaladdr:$in),
(HOR_addr (MOV_32_64_addr tglobaladdr:$in),
tglobaladdr:$in)>, Requires<[SBFv2]>;
tglobaladdr:$in)>, Requires<[SBFNoLddw]>;


def : Pat<(i64 (sext GPR32:$src)),
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/SBF/SBFSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ class SBFSubtarget : public SBFGenSubtargetInfo {
// reg - imm'.
bool ReverseSubImm;

// wether we should use the LDDW instruction
bool NoLddw;

public:
// This constructor initializes the data members to match that
// of the specified triple.
Expand All @@ -104,6 +107,7 @@ class SBFSubtarget : public SBFGenSubtargetInfo {
bool isSBFv2() const { return IsSBFv2; }
bool getDisableNeg() const { return DisableNeg; }
bool getReverseSubImm() const { return ReverseSubImm; }
bool getNoLddw() const { return NoLddw; }

const SBFInstrInfo *getInstrInfo() const override { return &InstrInfo; }
const SBFFrameLowering *getFrameLowering() const override {
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/CodeGen/SBF/objdump_cond_op.ll
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ define i32 @test(i32, i32) local_unnamed_addr #0 {
%10 = load i32, i32* @gbl, align 4
br i1 %9, label %15, label %11

; CHECK: mov32 w1, 0x0
; CHECK: mov32 r1, 0x0
; CHECK: hor64 r1, 0x0
; CHECK: ldxw r0, [r1 + 0x0]
; CHECK: mul64 r0, r0
Expand All @@ -46,7 +46,7 @@ define i32 @test(i32, i32) local_unnamed_addr #0 {
br label %13

; CHECK-LABEL: <LBB0_2>:
; CHECK: mov32 w3, 0x0
; CHECK: mov32 r3, 0x0
; CHECK: hor64 r3, 0x0
; CHECK: ldxw r0, [r3 + 0x0]
; CHECK: lsh64 r2, 0x20
Expand All @@ -59,7 +59,7 @@ define i32 @test(i32, i32) local_unnamed_addr #0 {
store i32 %14, i32* @gbl, align 4
br label %15
; CHECK-LABEL: <LBB0_4>:
; CHECK: mov32 w1, 0x0
; CHECK: mov32 r1, 0x0
; CHECK: hor64 r1, 0x0
; CHECK: stxw [r1 + 0x0], r0

Expand Down
16 changes: 8 additions & 8 deletions llvm/test/CodeGen/SBF/objdump_imm_hex.ll
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ define i32 @test(i64, i64) local_unnamed_addr #0 {
; CHECK-LABEL: test
%3 = icmp eq i64 %0, -6067004223159161907
br i1 %3, label %4, label %8
; CHECK-DEC: b4 03 00 00 cd ab cd ab mov32 w3, -0x54325433
; CHECK-DEC: b4 03 00 00 cd ab cd ab mov32 r3, -0x54325433
; CHECK-DEC: f7 03 00 00 cd ab cd ab hor64 r3, -0x54325433
; CHECK-DEC: 5d 31 07 00 00 00 00 00 jne r1, r3, +0x7
; CHECK-HEX: b4 03 00 00 cd ab cd ab mov32 w3, -0x54325433
; CHECK-HEX: b4 03 00 00 cd ab cd ab mov32 r3, -0x54325433
; CHECK-HEX: f7 03 00 00 cd ab cd ab hor64 r3, -0x54325433
; CHECK-HEX: 5d 31 07 00 00 00 00 00 jne r1, r3, +0x7

; <label>:4: ; preds = %2
; CHECK-DEC: b4 01 00 00 00 00 00 00 mov32 w1, 0x0
; CHECK-DEC: b4 01 00 00 00 00 00 00 mov32 r1, 0x0
; CHECK-DEC: f7 01 00 00 00 00 00 00 hor64 r1, 0x0
; CHECK-HEX: b4 01 00 00 00 00 00 00 mov32 w1, 0x0
; CHECK-HEX: b4 01 00 00 00 00 00 00 mov32 r1, 0x0
; CHECK-HEX: f7 01 00 00 00 00 00 00 hor64 r1, 0x0
; CHECK-REL: fixup A - offset: 0, value: gbl, kind: FK_SecRel_8
%5 = load i32, i32* @gbl, align 4
Expand All @@ -48,16 +48,16 @@ define i32 @test(i64, i64) local_unnamed_addr #0 {

; <label>:8: ; preds = %2
%9 = icmp eq i64 %1, 188899839028173
; CHECK-DEC: b4 01 00 00 cd ab cd ab mov32 w1, -0x54325433
; CHECK-DEC: b4 01 00 00 cd ab cd ab mov32 r1, -0x54325433
; CHECK-DEC: f7 01 00 00 cd ab 00 00 hor64 r1, 0xabcd
; CHECK-HEX: b4 01 00 00 cd ab cd ab mov32 w1, -0x54325433
; CHECK-HEX: b4 01 00 00 cd ab cd ab mov32 r1, -0x54325433
; CHECK-HEX: f7 01 00 00 cd ab 00 00 hor64 r1, 0xabcd
br i1 %9, label %10, label %16

; <label>:10: ; preds = %8
; CHECK-DEC: b4 01 00 00 00 00 00 00 mov32 w1, 0x0
; CHECK-DEC: b4 01 00 00 00 00 00 00 mov32 r1, 0x0
; CHECK-DEC: f7 01 00 00 00 00 00 00 hor64 r1, 0x0
; CHECK-HEX: b4 01 00 00 00 00 00 00 mov32 w1, 0x0
; CHECK-HEX: b4 01 00 00 00 00 00 00 mov32 r1, 0x0
; CHECK-HEX: f7 01 00 00 00 00 00 00 hor64 r1, 0x0
; CHECK-REL: fixup A - offset: 0, value: gbl, kind: FK_SecRel_8
%11 = load i32, i32* @gbl, align 4
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/SBF/objdump_static_var.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
; Function Attrs: norecurse nounwind
define dso_local i32 @test() local_unnamed_addr #0 {
%1 = load volatile i64, i64* @a, align 8, !tbaa !2
; CHECK: mov32 w1, 0x0
; CHECK: mov32 r1, 0x0
; CHECK: R_SBF_64_64 a
; CHECK: hor64 r1, 0x0
; CHECK: ldxdw r1, [r1 + 0x0]
%2 = load volatile i32, i32* @b, align 4, !tbaa !6
; CHECK: mov32 w2, 0x0
; CHECK: mov32 r2, 0x0
; CHECK: R_SBF_64_64 b
; CHECK: hor64 r2, 0x0
; CHECK: ldxw r0, [r2 + 0x0]
Expand Down
10 changes: 6 additions & 4 deletions llvm/test/MC/SBF/insn-unit-32.s
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# RUN: llvm-mc -triple sbf --mcpu=sbfv2 -filetype=obj -o %t %s
# RUN: llvm-objdump -d -r %t | FileCheck %s
# RUN: llvm-objdump --mattr=+alu32 -d -r %t | FileCheck %s
# RUN: llvm-objdump -d -r %t | FileCheck %s --check-prefixes=CHECK,CHECK-alu64
# RUN: llvm-objdump --mattr=+alu32 -d -r %t | FileCheck %s --check-prefixes=CHECK,CHECK-alu32

// ======== BPF_ALU Class ========
neg32 w1 // BPF_NEG
Expand Down Expand Up @@ -51,8 +51,10 @@
// CHECK: 64 06 00 00 3f 00 00 00 lsh32 w6, 0x3f
// CHECK: 74 07 00 00 20 00 00 00 rsh32 w7, 0x20
// CHECK: a4 08 00 00 00 00 00 00 xor32 w8, 0x0
// CHECK: b4 09 00 00 01 00 00 00 mov32 w9, 0x1
// CHECK: b4 09 00 00 ff ff ff ff mov32 w9, -0x1
// CHECK-alu64: b4 09 00 00 01 00 00 00 mov32 r9, 0x1
// CHECK-alu64: b4 09 00 00 ff ff ff ff mov32 r9, -0x1
// CHECK-alu32: b4 09 00 00 01 00 00 00 mov32 w9, 0x1
// CHECK-alu32: b4 09 00 00 ff ff ff ff mov32 w9, -0x1
// CHECK: c4 0a 00 00 40 00 00 00 arsh32 w10, 0x40

jeq w0, w1, Llabel0 // BPF_JEQ | BPF_X
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/MC/SBF/sbf-alu.s
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# RUN: llvm-mc %s -triple=sbf-solana-solana --mcpu=sbfv2 --show-encoding \
# RUN: | FileCheck %s --check-prefix=CHECK-ASM-NEW
# RUN: llvm-mc %s -triple=sbf-solana-solana --mcpu=sbfv2 -filetype=obj \
# RUN: | llvm-objdump -d -r - \
# RUN: | llvm-objdump -d -r --mattr=+alu32 - \
# RUN: | FileCheck --check-prefix=CHECK-OBJ-NEW %s


Expand Down
9 changes: 9 additions & 0 deletions llvm/tools/llvm-objdump/llvm-objdump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2061,6 +2061,15 @@ static void disassembleObject(ObjectFile *Obj, bool InlineRelocs) {
}
}

// The SBF target specifies the cpu type as an ELF flag, which is not parsed automatically in LLVM objdump.
// We must set the CPU type here so that the disassembler can decode the SBFv2 features correctly.
if (MCPU.empty() && Obj->isELF() && Obj->getArch() == Triple::sbf) {
const auto *Elf64 = dyn_cast<ELF64LEObjectFile>(Obj);
if (Elf64->getPlatformFlags() & ELF::EF_SBF_V2) {
MCPU = "sbfv2";
}
}

std::unique_ptr<const MCSubtargetInfo> STI(
TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
if (!STI)
Expand Down
Loading