summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAlexei Starovoitov <alexei.starovoitov@gmail.com>2016-11-18 02:32:35 +0000
committerAlexei Starovoitov <alexei.starovoitov@gmail.com>2016-11-18 02:32:35 +0000
commit8f9f8210c1f4846e70642595aab81e527dc5336c (patch)
tree2ead9a7b483faa203c4bbcd7ffced8616ff496c8 /llvm/lib
parentfaad4c30fa4ebf2d766944b558a38f15695ebe1b (diff)
downloadbcm5719-llvm-8f9f8210c1f4846e70642595aab81e527dc5336c.tar.gz
bcm5719-llvm-8f9f8210c1f4846e70642595aab81e527dc5336c.zip
convert bpf assembler to look like kernel verifier output
since bpf instruction set was introduced people learned to read and understand kernel verifier output whereas llvm asm output stayed obscure and unknown. Convert llvm to emit assembler text similar to kernel to avoid this discrepancy Signed-off-by: Alexei Starovoitov <ast@kernel.org> llvm-svn: 287300
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/BPF/BPF.td6
-rw-r--r--llvm/lib/Target/BPF/BPFInstrInfo.td102
-rw-r--r--llvm/lib/Target/BPF/InstPrinter/BPFInstPrinter.cpp18
3 files changed, 69 insertions, 57 deletions
diff --git a/llvm/lib/Target/BPF/BPF.td b/llvm/lib/Target/BPF/BPF.td
index 8493b0fd1e4..11abe520c50 100644
--- a/llvm/lib/Target/BPF/BPF.td
+++ b/llvm/lib/Target/BPF/BPF.td
@@ -25,14 +25,20 @@ def BPFInstPrinter : AsmWriter {
bit isMCAsmWriter = 1;
}
+def BPFAsmParser : AsmParser {
+ bit HasMnemonicFirst = 0;
+}
+
def BPFAsmParserVariant : AsmParserVariant {
int Variant = 0;
string Name = "BPF";
string BreakCharacters = ".";
+ string TokenizingCharacters = "#()[]=:.<>!+*";
}
def BPF : Target {
let InstructionSet = BPFInstrInfo;
let AssemblyWriters = [BPFInstPrinter];
+ let AssemblyParsers = [BPFAsmParser];
let AssemblyParserVariants = [BPFAsmParserVariant];
}
diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.td b/llvm/lib/Target/BPF/BPFInstrInfo.td
index 6b73db87fa2..1f766bfe21e 100644
--- a/llvm/lib/Target/BPF/BPFInstrInfo.td
+++ b/llvm/lib/Target/BPF/BPFInstrInfo.td
@@ -81,7 +81,7 @@ def BPF_CC_GEU : PatLeaf<(imm),
// jump instructions
class JMP_RR<bits<4> Opc, string OpcodeStr, PatLeaf Cond>
: InstBPF<(outs), (ins GPR:$dst, GPR:$src, brtarget:$BrDst),
- !strconcat(OpcodeStr, "\t$dst, $src goto $BrDst"),
+ "if $dst "#OpcodeStr#" $src goto $BrDst",
[(BPFbrcc i64:$dst, i64:$src, Cond, bb:$BrDst)]> {
bits<4> op;
bits<1> BPFSrc;
@@ -102,7 +102,7 @@ class JMP_RR<bits<4> Opc, string OpcodeStr, PatLeaf Cond>
class JMP_RI<bits<4> Opc, string OpcodeStr, PatLeaf Cond>
: InstBPF<(outs), (ins GPR:$dst, i64imm:$imm, brtarget:$BrDst),
- !strconcat(OpcodeStr, "i\t$dst, $imm goto $BrDst"),
+ "if $dst "#OpcodeStr#" $imm goto $BrDst",
[(BPFbrcc i64:$dst, i64immSExt32:$imm, Cond, bb:$BrDst)]> {
bits<4> op;
bits<1> BPFSrc;
@@ -128,18 +128,18 @@ multiclass J<bits<4> Opc, string OpcodeStr, PatLeaf Cond> {
let isBranch = 1, isTerminator = 1, hasDelaySlot=0 in {
// cmp+goto instructions
-defm JEQ : J<0x1, "jeq", BPF_CC_EQ>;
-defm JUGT : J<0x2, "jgt", BPF_CC_GTU>;
-defm JUGE : J<0x3, "jge", BPF_CC_GEU>;
-defm JNE : J<0x5, "jne", BPF_CC_NE>;
-defm JSGT : J<0x6, "jsgt", BPF_CC_GT>;
-defm JSGE : J<0x7, "jsge", BPF_CC_GE>;
+defm JEQ : J<0x1, "==", BPF_CC_EQ>;
+defm JUGT : J<0x2, ">", BPF_CC_GTU>;
+defm JUGE : J<0x3, ">=", BPF_CC_GEU>;
+defm JNE : J<0x5, "!=", BPF_CC_NE>;
+defm JSGT : J<0x6, "s>", BPF_CC_GT>;
+defm JSGE : J<0x7, "s>=", BPF_CC_GE>;
}
// ALU instructions
class ALU_RI<bits<4> Opc, string OpcodeStr, SDNode OpNode>
: InstBPF<(outs GPR:$dst), (ins GPR:$src2, i64imm:$imm),
- !strconcat(OpcodeStr, "i\t$dst, $imm"),
+ "$dst "#OpcodeStr#" $imm",
[(set GPR:$dst, (OpNode GPR:$src2, i64immSExt32:$imm))]> {
bits<4> op;
bits<1> BPFSrc;
@@ -158,7 +158,7 @@ class ALU_RI<bits<4> Opc, string OpcodeStr, SDNode OpNode>
class ALU_RR<bits<4> Opc, string OpcodeStr, SDNode OpNode>
: InstBPF<(outs GPR:$dst), (ins GPR:$src2, GPR:$src),
- !strconcat(OpcodeStr, "\t$dst, $src"),
+ "$dst "#OpcodeStr#" $src",
[(set GPR:$dst, (OpNode i64:$src2, i64:$src))]> {
bits<4> op;
bits<1> BPFSrc;
@@ -182,22 +182,22 @@ multiclass ALU<bits<4> Opc, string OpcodeStr, SDNode OpNode> {
let Constraints = "$dst = $src2" in {
let isAsCheapAsAMove = 1 in {
- defm ADD : ALU<0x0, "add", add>;
- defm SUB : ALU<0x1, "sub", sub>;
- defm OR : ALU<0x4, "or", or>;
- defm AND : ALU<0x5, "and", and>;
- defm SLL : ALU<0x6, "sll", shl>;
- defm SRL : ALU<0x7, "srl", srl>;
- defm XOR : ALU<0xa, "xor", xor>;
- defm SRA : ALU<0xc, "sra", sra>;
+ defm ADD : ALU<0x0, "+=", add>;
+ defm SUB : ALU<0x1, "-=", sub>;
+ defm OR : ALU<0x4, "|=", or>;
+ defm AND : ALU<0x5, "&=", and>;
+ defm SLL : ALU<0x6, "<<=", shl>;
+ defm SRL : ALU<0x7, ">>=", srl>;
+ defm XOR : ALU<0xa, "^=", xor>;
+ defm SRA : ALU<0xc, "s>>=", sra>;
}
- defm MUL : ALU<0x2, "mul", mul>;
- defm DIV : ALU<0x3, "div", udiv>;
+ defm MUL : ALU<0x2, "*=", mul>;
+ defm DIV : ALU<0x3, "/=", udiv>;
}
class MOV_RR<string OpcodeStr>
: InstBPF<(outs GPR:$dst), (ins GPR:$src),
- !strconcat(OpcodeStr, "\t$dst, $src"),
+ "$dst "#OpcodeStr#" $src",
[]> {
bits<4> op;
bits<1> BPFSrc;
@@ -216,7 +216,7 @@ class MOV_RR<string OpcodeStr>
class MOV_RI<string OpcodeStr>
: InstBPF<(outs GPR:$dst), (ins i64imm:$imm),
- !strconcat(OpcodeStr, "\t$dst, $imm"),
+ "$dst "#OpcodeStr#" $imm",
[(set GPR:$dst, (i64 i64immSExt32:$imm))]> {
bits<4> op;
bits<1> BPFSrc;
@@ -235,7 +235,7 @@ class MOV_RI<string OpcodeStr>
class LD_IMM64<bits<4> Pseudo, string OpcodeStr>
: InstBPF<(outs GPR:$dst), (ins u64imm:$imm),
- !strconcat(OpcodeStr, "\t$dst, $imm"),
+ "$dst "#OpcodeStr#" ${imm}ll",
[(set GPR:$dst, (i64 imm:$imm))]> {
bits<3> mode;
@@ -256,9 +256,9 @@ class LD_IMM64<bits<4> Pseudo, string OpcodeStr>
}
let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
-def LD_imm64 : LD_IMM64<0, "ld_64">;
-def MOV_rr : MOV_RR<"mov">;
-def MOV_ri : MOV_RI<"mov">;
+def LD_imm64 : LD_IMM64<0, "=">;
+def MOV_rr : MOV_RR<"=">;
+def MOV_ri : MOV_RI<"=">;
}
def FI_ri
@@ -296,7 +296,7 @@ def LD_pseudo
// STORE instructions
class STORE<bits<2> SizeOp, string OpcodeStr, list<dag> Pattern>
: InstBPF<(outs), (ins GPR:$src, MEMri:$addr),
- !strconcat(OpcodeStr, "\t$addr, $src"), Pattern> {
+ "*("#OpcodeStr#" *)($addr) = $src", Pattern> {
bits<3> mode;
bits<2> size;
bits<4> src;
@@ -316,15 +316,15 @@ class STORE<bits<2> SizeOp, string OpcodeStr, list<dag> Pattern>
class STOREi64<bits<2> Opc, string OpcodeStr, PatFrag OpNode>
: STORE<Opc, OpcodeStr, [(OpNode i64:$src, ADDRri:$addr)]>;
-def STW : STOREi64<0x0, "stw", truncstorei32>;
-def STH : STOREi64<0x1, "sth", truncstorei16>;
-def STB : STOREi64<0x2, "stb", truncstorei8>;
-def STD : STOREi64<0x3, "std", store>;
+def STW : STOREi64<0x0, "u32", truncstorei32>;
+def STH : STOREi64<0x1, "u16", truncstorei16>;
+def STB : STOREi64<0x2, "u8", truncstorei8>;
+def STD : STOREi64<0x3, "u64", store>;
// LOAD instructions
class LOAD<bits<2> SizeOp, string OpcodeStr, list<dag> Pattern>
: InstBPF<(outs GPR:$dst), (ins MEMri:$addr),
- !strconcat(OpcodeStr, "\t$dst, $addr"), Pattern> {
+ "$dst = *("#OpcodeStr#" *)($addr)", Pattern> {
bits<3> mode;
bits<2> size;
bits<4> dst;
@@ -344,14 +344,14 @@ class LOAD<bits<2> SizeOp, string OpcodeStr, list<dag> Pattern>
class LOADi64<bits<2> SizeOp, string OpcodeStr, PatFrag OpNode>
: LOAD<SizeOp, OpcodeStr, [(set i64:$dst, (OpNode ADDRri:$addr))]>;
-def LDW : LOADi64<0x0, "ldw", zextloadi32>;
-def LDH : LOADi64<0x1, "ldh", zextloadi16>;
-def LDB : LOADi64<0x2, "ldb", zextloadi8>;
-def LDD : LOADi64<0x3, "ldd", load>;
+def LDW : LOADi64<0x0, "u32", zextloadi32>;
+def LDH : LOADi64<0x1, "u16", zextloadi16>;
+def LDB : LOADi64<0x2, "u8", zextloadi8>;
+def LDD : LOADi64<0x3, "u64", load>;
class BRANCH<bits<4> Opc, string OpcodeStr, list<dag> Pattern>
: InstBPF<(outs), (ins brtarget:$BrDst),
- !strconcat(OpcodeStr, "\t$BrDst"), Pattern> {
+ !strconcat(OpcodeStr, " $BrDst"), Pattern> {
bits<4> op;
bits<16> BrDst;
bits<1> BPFSrc;
@@ -367,7 +367,7 @@ class BRANCH<bits<4> Opc, string OpcodeStr, list<dag> Pattern>
class CALL<string OpcodeStr>
: InstBPF<(outs), (ins calltarget:$BrDst),
- !strconcat(OpcodeStr, "\t$BrDst"), []> {
+ !strconcat(OpcodeStr, " $BrDst"), []> {
bits<4> op;
bits<32> BrDst;
bits<1> BPFSrc;
@@ -383,7 +383,7 @@ class CALL<string OpcodeStr>
// Jump always
let isBranch = 1, isTerminator = 1, hasDelaySlot=0, isBarrier = 1 in {
- def JMP : BRANCH<0x0, "jmp", [(br bb:$BrDst)]>;
+ def JMP : BRANCH<0x0, "goto", [(br bb:$BrDst)]>;
}
// Jump and link
@@ -432,7 +432,7 @@ class RET<string OpcodeStr>
let isReturn = 1, isTerminator = 1, hasDelaySlot=0, isBarrier = 1,
isNotDuplicable = 1 in {
- def RET : RET<"ret">;
+ def RET : RET<"exit">;
}
// ADJCALLSTACKDOWN/UP pseudo insns
@@ -472,7 +472,7 @@ def : Pat<(extloadi32 ADDRri:$src), (i64 (LDW ADDRri:$src))>;
// Atomics
class XADD<bits<2> SizeOp, string OpcodeStr, PatFrag OpNode>
: InstBPF<(outs GPR:$dst), (ins MEMri:$addr, GPR:$val),
- !strconcat(OpcodeStr, "\t$dst, $addr, $val"),
+ "lock *("#OpcodeStr#" *)($addr) += $val",
[(set GPR:$dst, (OpNode ADDRri:$addr, GPR:$val))]> {
bits<3> mode;
bits<2> size;
@@ -491,8 +491,8 @@ class XADD<bits<2> SizeOp, string OpcodeStr, PatFrag OpNode>
}
let Constraints = "$dst = $val" in {
-def XADD32 : XADD<0, "xadd32", atomic_load_add_32>;
-def XADD64 : XADD<3, "xadd64", atomic_load_add_64>;
+def XADD32 : XADD<0, "u32", atomic_load_add_32>;
+def XADD64 : XADD<3, "u64", atomic_load_add_64>;
// undefined def XADD16 : XADD<1, "xadd16", atomic_load_add_16>;
// undefined def XADD8 : XADD<2, "xadd8", atomic_load_add_8>;
}
@@ -528,7 +528,7 @@ let Defs = [R0, R1, R2, R3, R4, R5], Uses = [R6], hasSideEffects = 1,
hasExtraDefRegAllocReq = 1, hasExtraSrcRegAllocReq = 1, mayLoad = 1 in {
class LOAD_ABS<bits<2> SizeOp, string OpcodeStr, Intrinsic OpNode>
: InstBPF<(outs), (ins GPR:$skb, i64imm:$imm),
- !strconcat(OpcodeStr, "\tr0, $skb.data + $imm"),
+ "r0 = *("#OpcodeStr#" *)skb[$imm]",
[(set R0, (OpNode GPR:$skb, i64immSExt32:$imm))]> {
bits<3> mode;
bits<2> size;
@@ -545,7 +545,7 @@ class LOAD_ABS<bits<2> SizeOp, string OpcodeStr, Intrinsic OpNode>
class LOAD_IND<bits<2> SizeOp, string OpcodeStr, Intrinsic OpNode>
: InstBPF<(outs), (ins GPR:$skb, GPR:$val),
- !strconcat(OpcodeStr, "\tr0, $skb.data + $val"),
+ "r0 = *("#OpcodeStr#" *)skb[$val]",
[(set R0, (OpNode GPR:$skb, GPR:$val))]> {
bits<3> mode;
bits<2> size;
@@ -561,10 +561,10 @@ class LOAD_IND<bits<2> SizeOp, string OpcodeStr, Intrinsic OpNode>
}
}
-def LD_ABS_B : LOAD_ABS<2, "ldabs_b", int_bpf_load_byte>;
-def LD_ABS_H : LOAD_ABS<1, "ldabs_h", int_bpf_load_half>;
-def LD_ABS_W : LOAD_ABS<0, "ldabs_w", int_bpf_load_word>;
+def LD_ABS_B : LOAD_ABS<2, "u8", int_bpf_load_byte>;
+def LD_ABS_H : LOAD_ABS<1, "u16", int_bpf_load_half>;
+def LD_ABS_W : LOAD_ABS<0, "u32", int_bpf_load_word>;
-def LD_IND_B : LOAD_IND<2, "ldind_b", int_bpf_load_byte>;
-def LD_IND_H : LOAD_IND<1, "ldind_h", int_bpf_load_half>;
-def LD_IND_W : LOAD_IND<0, "ldind_w", int_bpf_load_word>;
+def LD_IND_B : LOAD_IND<2, "u8", int_bpf_load_byte>;
+def LD_IND_H : LOAD_IND<1, "u16", int_bpf_load_half>;
+def LD_IND_W : LOAD_IND<0, "u32", int_bpf_load_word>;
diff --git a/llvm/lib/Target/BPF/InstPrinter/BPFInstPrinter.cpp b/llvm/lib/Target/BPF/InstPrinter/BPFInstPrinter.cpp
index 552288b819d..ffd29f3ea99 100644
--- a/llvm/lib/Target/BPF/InstPrinter/BPFInstPrinter.cpp
+++ b/llvm/lib/Target/BPF/InstPrinter/BPFInstPrinter.cpp
@@ -67,15 +67,21 @@ void BPFInstPrinter::printMemOperand(const MCInst *MI, int OpNo, raw_ostream &O,
const char *Modifier) {
const MCOperand &RegOp = MI->getOperand(OpNo);
const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
- // offset
- if (OffsetOp.isImm())
- O << formatDec(OffsetOp.getImm());
- else
- assert(0 && "Expected an immediate");
// register
assert(RegOp.isReg() && "Register operand not a register");
- O << '(' << getRegisterName(RegOp.getReg()) << ')';
+ O << getRegisterName(RegOp.getReg());
+
+ // offset
+ if (OffsetOp.isImm()) {
+ auto Imm = OffsetOp.getImm();
+ if (Imm >= 0)
+ O << " + " << formatDec(Imm);
+ else
+ O << " - " << formatDec(-Imm);
+ } else {
+ assert(0 && "Expected an immediate");
+ }
}
void BPFInstPrinter::printImm64Operand(const MCInst *MI, unsigned OpNo,
OpenPOWER on IntegriCloud