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] Implement syscall instruction #121

Merged
merged 3 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 3 additions & 1 deletion llvm/lib/Target/SBF/Disassembler/SBFDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class SBFDisassembler : public MCDisassembler {
uint8_t getInstMode(uint64_t Inst) const { return (Inst >> 61) & 0x7; };
bool isMov32(uint64_t Inst) const { return (Inst >> 56) == 0xb4; }
bool isNewMem(uint64_t Inst) const;
bool isSyscallOrExit(uint64_t Inst) const { return (Inst >> 56) == 0x95; }
};

} // end anonymous namespace
Expand Down Expand Up @@ -202,7 +203,8 @@ DecodeStatus SBFDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
Result =
decodeInstruction(DecoderTableSBFALU32MEMv264,
Instr, Insn, Address, this, STI);
else if (isNewMem(Insn) && STI.hasFeature(SBF::FeatureNewMemEncoding))
else if ((isNewMem(Insn) && STI.hasFeature(SBF::FeatureNewMemEncoding)) ||
(isSyscallOrExit(Insn) && STI.hasFeature(SBF::FeatureStaticSyscalls)))
Result =
decodeInstruction(DecoderTableSBFv264,
Instr, Insn, Address, this, STI);
Expand Down
17 changes: 15 additions & 2 deletions llvm/lib/Target/SBF/SBFISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ SDValue SBFTargetLowering::LowerFormalArguments(
}

const unsigned SBFTargetLowering::MaxArgs = 5;
const uint64_t SBFTargetLowering::MaxSyscall = 100;

SDValue SBFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
Expand Down Expand Up @@ -592,11 +593,21 @@ SDValue SBFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// If the callee is a GlobalAddress node (quite common, every direct call is)
// turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
// Likewise ExternalSymbol -> TargetExternalSymbol.
unsigned NodeCode = SBFISD::CALL;
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), CLI.DL, PtrVT,
G->getOffset(), 0);
} else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0);
} else if (ConstantSDNode * CNode = dyn_cast<ConstantSDNode>(Callee)) {
uint64_t Cte = CNode->getZExtValue();
uint64_t U32Max = static_cast<uint64_t>
(std::numeric_limits<uint32_t>::max());
if (Subtarget->getHasStaticSyscalls() && Cte >= U32Max - MaxSyscall) {
NodeCode = SBFISD::SYSCALL;
uint64_t SyscallCode = U32Max - Cte;
Callee = DAG.getConstant(SyscallCode, CLI.DL, MVT::i64);
}
}

// Returns a chain & a flag for retval copy to use.
Expand All @@ -610,14 +621,14 @@ SDValue SBFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
for (auto &Reg : RegsToPass)
Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));

if (HasStackArgs) {
if (HasStackArgs && !Subtarget->getHasDynamicFrames()) {
Ops.push_back(DAG.getRegister(SBF::R5, MVT::i64));
}

if (InGlue.getNode())
Ops.push_back(InGlue);

Chain = DAG.getNode(SBFISD::CALL, CLI.DL, NodeTys, Ops);
Chain = DAG.getNode(NodeCode, CLI.DL, NodeTys, Ops);
InGlue = Chain.getValue(1);

DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
Expand Down Expand Up @@ -919,6 +930,8 @@ const char *SBFTargetLowering::getTargetNodeName(unsigned Opcode) const {
return "SBFISD::Wrapper";
case SBFISD::MEMCPY:
return "SBFISD::MEMCPY";
case SBFISD::SYSCALL:
return "SBFISD::SYSCALL";
}
return nullptr;
}
Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/Target/SBF/SBFISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ enum NodeType : unsigned {
SELECT_CC,
BR_CC,
Wrapper,
MEMCPY
MEMCPY,
SYSCALL,
};
}

Expand Down Expand Up @@ -90,6 +91,9 @@ class SBFTargetLowering : public TargetLowering {
// Maximum number of arguments to a call
static const unsigned MaxArgs;

// Maximum number of syscalls
static const uint64_t MaxSyscall;

// Lower a call into CALLSEQ_START - SBFISD:CALL - CALLSEQ_END chain
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const override;
Expand Down
27 changes: 14 additions & 13 deletions llvm/lib/Target/SBF/SBFInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,20 @@ class SBFJumpOp<bits<4> val> {
bits<4> Value = val;
}

def SBF_JA : SBFJumpOp<0x0>;
def SBF_JEQ : SBFJumpOp<0x1>;
def SBF_JGT : SBFJumpOp<0x2>;
def SBF_JGE : SBFJumpOp<0x3>;
def SBF_JNE : SBFJumpOp<0x5>;
def SBF_JSGT : SBFJumpOp<0x6>;
def SBF_JSGE : SBFJumpOp<0x7>;
def SBF_CALL : SBFJumpOp<0x8>;
def SBF_EXIT : SBFJumpOp<0x9>;
def SBF_JLT : SBFJumpOp<0xa>;
def SBF_JLE : SBFJumpOp<0xb>;
def SBF_JSLT : SBFJumpOp<0xc>;
def SBF_JSLE : SBFJumpOp<0xd>;
def SBF_JA : SBFJumpOp<0x0>;
def SBF_JEQ : SBFJumpOp<0x1>;
def SBF_JGT : SBFJumpOp<0x2>;
def SBF_JGE : SBFJumpOp<0x3>;
def SBF_JNE : SBFJumpOp<0x5>;
def SBF_JSGT : SBFJumpOp<0x6>;
def SBF_JSGE : SBFJumpOp<0x7>;
def SBF_CALL : SBFJumpOp<0x8>;
def SBF_EXIT : SBFJumpOp<0x9>;
def SBF_JLT : SBFJumpOp<0xa>;
def SBF_JLE : SBFJumpOp<0xb>;
def SBF_JSLT : SBFJumpOp<0xc>;
def SBF_JSLE : SBFJumpOp<0xd>;
def SBF_SYSCALL : SBFJumpOp<0x9>;

class SBFWidthModifer<bits<2> val> {
bits<2> Value = val;
Expand Down
20 changes: 19 additions & 1 deletion llvm/lib/Target/SBF/SBFInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@ def SDT_SBFMEMCPY : SDTypeProfile<0, 4, [SDTCisVT<0, i64>,
SDTCisVT<1, i64>,
SDTCisVT<2, i64>,
SDTCisVT<3, i64>]>;
def SDT_SBFSyscall : SDTypeProfile<0, 1, [SDTCisVT<0, i64>]>;

def SBFcall : SDNode<"SBFISD::CALL", SDT_SBFCall,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
SDNPVariadic]>;
def SBFSyscall : SDNode<"SBFISD::SYSCALL", SDT_SBFSyscall,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
def SBFretglue : SDNode<"SBFISD::RET_GLUE", SDTNone,
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
def SBFcallseq_start: SDNode<"ISD::CALLSEQ_START", SDT_SBFCallSeqStart,
Expand Down Expand Up @@ -801,6 +804,19 @@ class CALL<string OpcodeStr>
let SBFClass = SBF_JMP;
}

class SYSCALL<string OpcodeStr>
: TYPE_ALU_JMP<SBF_SYSCALL.Value, SBF_K.Value,
(outs),
(ins i64imm:$imm),
!strconcat(OpcodeStr, " $imm"),
[]> {
bits<32> imm;

let Inst{31-0} = imm;
let SBFClass = SBF_JMP;
}


class CALLX<string OpcodeStr>
: TYPE_ALU_JMP<SBF_CALL.Value, SBF_X.Value,
(outs),
Expand Down Expand Up @@ -838,6 +854,7 @@ let isCall=1, hasDelaySlot=0, Uses = [R10],
def JALX : CALLX<"callx">, Requires<[SBFNoCallxSrc]>;
let DecoderNamespace = "SBFv2" in {
def JALX_v2 : CALLX_SRC_REG<"callx">, Requires<[SBFCallxSrc]>;
def SYSCALL_v3 : SYSCALL<"syscall">, Requires<[SBFHasStaticSyscalls]>;
}
}

Expand Down Expand Up @@ -883,7 +900,7 @@ class RETURN<string OpcodeStr>

let isReturn = 1, isTerminator = 1, hasDelaySlot=0, isBarrier = 1,
isNotDuplicable = 1, Predicates = [SBFHasStaticSyscalls] in {
def RETURN : RETURN<"return">;
def RETURN_v3 : RETURN<"return">;
}

// ADJCALLSTACKDOWN/UP pseudo insns
Expand Down Expand Up @@ -949,6 +966,7 @@ def : Pat<(SBFcall texternalsym:$dst), (JAL texternalsym:$dst)>;
def : Pat<(SBFcall imm:$dst), (JAL imm:$dst)>;
def : Pat<(SBFcall GPR:$dst), (JALX GPR:$dst)>, Requires<[SBFNoCallxSrc]>;
def : Pat<(SBFcall GPR:$dst), (JALX_v2 GPR:$dst)>, Requires<[SBFCallxSrc]>;
def : Pat<(SBFSyscall imm:$imm), (SYSCALL_v3 imm:$imm)>, Requires<[SBFHasStaticSyscalls]>;

// Loads
let Predicates = [SBFNoALU32, SBFOldMemEncoding] in {
Expand Down
25 changes: 25 additions & 0 deletions llvm/test/CodeGen/SBF/static_syscall.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
; RUN: llc -march=sbf < %s | FileCheck --check-prefix=CHECK-V1 %s
; RUN: llc -march=sbf -mattr=+static-syscalls -show-mc-encoding < %s | FileCheck --check-prefix=CHECK-V2 %s


; Function Attrs: nounwind
define dso_local i32 @test(i32 noundef %a, i32 noundef %b) {
entry:
; CHECK-LABEL: test

; CHECK-V1: call -2
; CHECK-V2: syscall 1 # encoding: [0x95,0x00,0x00,0x00,0x01,0x00,0x00,0x00]
%syscall_1 = tail call i32 inttoptr (i64 4294967294 to ptr)(i32 noundef %a, i32 noundef %b)

; CHECK-V1: call -12
; CHECK-V2: syscall 11 # encoding: [0x95,0x00,0x00,0x00,0x0b,0x00,0x00,0x00]
%syscall_2 = tail call i32 inttoptr (i64 4294967284 to ptr)(i32 noundef %a, i32 noundef %b)

; CHECK-V1: call -112
; CHECK-V2: call -112
%not_syscall = tail call i32 inttoptr (i64 4294967184 to ptr)(i32 noundef %a, i32 noundef %b)

%add_1 = add i32 %syscall_1, %syscall_2
%add_2 = add i32 %add_1, %not_syscall
ret i32 %add_1
}
6 changes: 6 additions & 0 deletions llvm/test/MC/Disassembler/SBF/sbf-jmp.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# RUN: llvm-mc --disassemble %s -triple=sbf-solana-solana \
# RUN: | FileCheck %s --check-prefix=CHECK-NEW
# RUN: llvm-mc --disassemble %s -triple=sbf-solana-solana -mattr=+static-syscalls \
# RUN: | FileCheck %s --check-prefix=CHECK-V2

# TODO: Test immediate field ranges.

Expand Down Expand Up @@ -109,5 +111,9 @@
# CHECK-NEW: exit
0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x00

# CHECK-V2: syscall 5
0x95,0x00,0x00,0x00,0x05,0x00,0x00,0x00


# CHECK-NEW: return
0x9d,0x00,0x00,0x00,0x00,0x00,0x00,0x00
4 changes: 1 addition & 3 deletions llvm/test/MC/SBF/insn-unit.s
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,8 @@
// ======== BPF_JMP Class ========
ja Llabel0 // BPF_JA
call 1 // BPF_CALL
exit // BPF_EXIT
// CHECK: 05 00 1a 00 00 00 00 00 ja +0x1a
// CHECK: 05 00 19 00 00 00 00 00 ja +0x19
// CHECK: 85 00 00 00 01 00 00 00 call 0x1
// CHECK: 95 00 00 00 00 00 00 00 exit

jeq r0, r1, Llabel0 // BPF_JEQ | BPF_X
jne r3, r4, Llabel0 // BPF_JNE | BPF_X
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/MC/SBF/sbf-jmp.s
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,6 @@ call 8
# CHECK-ASM-OLD: encoding: [0x8d,0x00,0x00,0x00,0x04,0x00,0x00,0x00]
callx r4

# CHECK-OBJ-NEW: exit
# CHECK-ASM-NEW: encoding: [0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
# CHECK-OBJ-OLD: exit
# CHECK-ASM-OLD: encoding: [0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
exit
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# RUN: llvm-mc -triple=sbf-solana-solana --mcpu=sbfv2 -filetype=obj -o %t %s
# RUN: llvm-objdump -d -r %t | FileCheck --check-prefix=CHECK %s

syscall 9
return

// CHECK: 95 00 00 00 09 00 00 00 syscall 0x9
// CHECK: 9d 00 00 00 00 00 00 00 return
Loading