aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/config/bpf/bpf-opts.h6
-rw-r--r--gcc/config/bpf/bpf.cc46
-rw-r--r--gcc/config/bpf/bpf.h5
-rw-r--r--gcc/config/bpf/bpf.md97
-rw-r--r--gcc/config/bpf/bpf.opt14
-rw-r--r--gcc/doc/invoke.texi21
6 files changed, 133 insertions, 56 deletions
diff --git a/gcc/config/bpf/bpf-opts.h b/gcc/config/bpf/bpf-opts.h
index 8282351..92db01e 100644
--- a/gcc/config/bpf/bpf-opts.h
+++ b/gcc/config/bpf/bpf-opts.h
@@ -60,4 +60,10 @@ enum bpf_isa_version
ISA_V3,
};
+enum bpf_asm_dialect
+{
+ ASM_NORMAL,
+ ASM_PSEUDOC
+};
+
#endif /* ! BPF_OPTS_H */
diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index e0324e1..1d39368 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -873,16 +873,47 @@ bpf_output_call (rtx target)
return "";
}
+/* Print register name according to assembly dialect.
+ In normal syntax registers are printed like %rN where N is the
+ register number.
+ In pseudoc syntax, the register names do not feature a '%' prefix.
+ Additionally, the code 'w' denotes that the register should be printed
+ as wN instead of rN, where N is the register number, but only when the
+ value stored in the operand OP is 32-bit wide. */
+static void
+bpf_print_register (FILE *file, rtx op, int code)
+{
+ if(asm_dialect == ASM_NORMAL)
+ fprintf (file, "%s", reg_names[REGNO (op)]);
+ else
+ {
+ if (code == 'w' && GET_MODE (op) == SImode)
+ {
+ if (REGNO (op) == BPF_FP)
+ fprintf (file, "w10");
+ else
+ fprintf (file, "w%s", reg_names[REGNO (op)]+2);
+ }
+ else
+ {
+ if (REGNO (op) == BPF_FP)
+ fprintf (file, "r10");
+ else
+ fprintf (file, "%s", reg_names[REGNO (op)]+1);
+ }
+ }
+}
+
/* Print an instruction operand. This function is called in the macro
PRINT_OPERAND defined in bpf.h */
void
-bpf_print_operand (FILE *file, rtx op, int code ATTRIBUTE_UNUSED)
+bpf_print_operand (FILE *file, rtx op, int code)
{
switch (GET_CODE (op))
{
case REG:
- fprintf (file, "%s", reg_names[REGNO (op)]);
+ bpf_print_register (file, op, code);
break;
case MEM:
output_address (GET_MODE (op), XEXP (op, 0));
@@ -936,7 +967,9 @@ bpf_print_operand_address (FILE *file, rtx addr)
switch (GET_CODE (addr))
{
case REG:
- fprintf (file, "[%s+0]", reg_names[REGNO (addr)]);
+ fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "(");
+ bpf_print_register (file, addr, 0);
+ fprintf (file, asm_dialect == ASM_NORMAL ? "+0]" : "+0)");
break;
case PLUS:
{
@@ -945,9 +978,11 @@ bpf_print_operand_address (FILE *file, rtx addr)
if (GET_CODE (op0) == REG && GET_CODE (op1) == CONST_INT)
{
- fprintf (file, "[%s+", reg_names[REGNO (op0)]);
+ fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "(");
+ bpf_print_register (file, op0, 0);
+ fprintf (file, "+");
output_addr_const (file, op1);
- fputs ("]", file);
+ fprintf (file, asm_dialect == ASM_NORMAL ? "]" : ")");
}
else
fatal_insn ("invalid address in operand", addr);
@@ -1816,7 +1851,6 @@ handle_attr_preserve (function *fn)
}
}
-
/* This pass finds accesses to structures marked with the BPF target attribute
__attribute__((preserve_access_index)). For every such access, a CO-RE
relocation record is generated, to be output in the .BTF.ext section. */
diff --git a/gcc/config/bpf/bpf.h b/gcc/config/bpf/bpf.h
index 344aca0..9561bf5 100644
--- a/gcc/config/bpf/bpf.h
+++ b/gcc/config/bpf/bpf.h
@@ -22,7 +22,8 @@
/**** Controlling the Compilation Driver. */
-#define ASM_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL} %{mxbpf:-mxbpf}"
+#define ASM_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL} %{mxbpf:-mxbpf} " \
+ "%{masm=pseudoc:-mdialect=pseudoc}"
#define LINK_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL}"
#define LIB_SPEC ""
#define STARTFILE_SPEC ""
@@ -503,4 +504,6 @@ enum reg_class
#define DO_GLOBAL_DTORS_BODY \
do { } while (0)
+#define ASSEMBLER_DIALECT ((int) asm_dialect)
+
#endif /* ! GCC_BPF_H */
diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
index adf11e1..80220f2 100644
--- a/gcc/config/bpf/bpf.md
+++ b/gcc/config/bpf/bpf.md
@@ -88,6 +88,8 @@
(define_mode_attr mop [(QI "b") (HI "h") (SI "w") (DI "dw")
(SF "w") (DF "dw")])
+(define_mode_attr smop [(QI "u8") (HI "u16") (SI "u32") (DI "u64")
+ (SF "u32") (DF "u64")])
(define_mode_attr mtype [(SI "alu32") (DI "alu")])
(define_mode_attr msuffix [(SI "32") (DI "")])
@@ -121,7 +123,7 @@
(plus:AM (match_operand:AM 1 "register_operand" " 0,0")
(match_operand:AM 2 "reg_or_imm_operand" " r,I")))]
"1"
- "add<msuffix>\t%0,%2"
+ "{add<msuffix>\t%0,%2|%w0 += %w1}"
[(set_attr "type" "<mtype>")])
;;; Subtraction
@@ -134,15 +136,15 @@
(minus:AM (match_operand:AM 1 "register_operand" " 0")
(match_operand:AM 2 "register_operand" " r")))]
""
- "sub<msuffix>\t%0,%2"
+ "{sub<msuffix>\t%0,%2|%w0 -= %w1}"
[(set_attr "type" "<mtype>")])
;;; Negation
(define_insn "neg<AM:mode>2"
- [(set (match_operand:AM 0 "register_operand" "=r,r")
- (neg:AM (match_operand:AM 1 "register_operand" " r,I")))]
+ [(set (match_operand:AM 0 "register_operand" "=r,r")
+ (neg:AM (match_operand:AM 1 "reg_or_imm_operand" " r,I")))]
""
- "neg<msuffix>\t%0,%1"
+ "{neg<msuffix>\t%0,%1|%w0 = -%w1}"
[(set_attr "type" "<mtype>")])
;;; Multiplication
@@ -151,7 +153,7 @@
(mult:AM (match_operand:AM 1 "register_operand" " 0,0")
(match_operand:AM 2 "reg_or_imm_operand" " r,I")))]
""
- "mul<msuffix>\t%0,%2"
+ "{mul<msuffix>\t%0,%2|%w0 *= %w2}"
[(set_attr "type" "<mtype>")])
(define_insn "*mulsidi3_zeroextend"
@@ -160,7 +162,7 @@
(mult:SI (match_operand:SI 1 "register_operand" "0,0")
(match_operand:SI 2 "reg_or_imm_operand" "r,I"))))]
""
- "mul32\t%0,%2"
+ "{mul32\t%0,%2|%w0 *= %w2}"
[(set_attr "type" "alu32")])
;;; Division
@@ -173,7 +175,7 @@
(udiv:AM (match_operand:AM 1 "register_operand" " 0,0")
(match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
""
- "div<msuffix>\t%0,%2"
+ "{div<msuffix>\t%0,%2|%w0 /= %w2}"
[(set_attr "type" "<mtype>")])
;; However, xBPF does provide a signed division operator, sdiv.
@@ -183,7 +185,7 @@
(div:AM (match_operand:AM 1 "register_operand" " 0,0")
(match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
"TARGET_XBPF"
- "sdiv<msuffix>\t%0,%2"
+ "{sdiv<msuffix>\t%0,%2|%w0 s/= %w2}"
[(set_attr "type" "<mtype>")])
;;; Modulus
@@ -196,7 +198,7 @@
(umod:AM (match_operand:AM 1 "register_operand" " 0,0")
(match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
""
- "mod<msuffix>\t%0,%2"
+ "{mod<msuffix>\t%0,%2|%w0 %%= %w2}"
[(set_attr "type" "<mtype>")])
;; Again, xBPF provides a signed version, smod.
@@ -206,7 +208,7 @@
(mod:AM (match_operand:AM 1 "register_operand" " 0,0")
(match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
"TARGET_XBPF"
- "smod<msuffix>\t%0,%2"
+ "{smod<msuffix>\t%0,%2|%w0 s%%= %w2}"
[(set_attr "type" "<mtype>")])
;;; Logical AND
@@ -215,7 +217,7 @@
(and:AM (match_operand:AM 1 "register_operand" " 0,0")
(match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
""
- "and<msuffix>\t%0,%2"
+ "{and<msuffix>\t%0,%2|%w0 &= %w2}"
[(set_attr "type" "<mtype>")])
;;; Logical inclusive-OR
@@ -224,7 +226,7 @@
(ior:AM (match_operand:AM 1 "register_operand" " 0,0")
(match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
""
- "or<msuffix>\t%0,%2"
+ "{or<msuffix>\t%0,%2|%w0 %|= %w2}"
[(set_attr "type" "<mtype>")])
;;; Logical exclusive-OR
@@ -233,7 +235,7 @@
(xor:AM (match_operand:AM 1 "register_operand" " 0,0")
(match_operand:AM 2 "reg_or_imm_operand" "r,I")))]
""
- "xor<msuffix>\t%0,%2"
+ "{xor<msuffix>\t%0,%2|%w0 ^= %w2}"
[(set_attr "type" "<mtype>")])
;;;; Conversions
@@ -256,9 +258,9 @@
(zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "0,r,q")))]
""
"@
- and\t%0,0xffff
- mov\t%0,%1\;and\t%0,0xffff
- ldxh\t%0,%1"
+ {and\t%0,0xffff|%0 &= 0xffff}
+ {mov\t%0,%1\;and\t%0,0xffff|%0 = %1;%0 &= 0xffff}
+ {ldxh\t%0,%1|%0 = *(u16 *) %1}"
[(set_attr "type" "alu,alu,ldx")])
(define_insn "zero_extendqidi2"
@@ -266,9 +268,9 @@
(zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "0,r,q")))]
""
"@
- and\t%0,0xff
- mov\t%0,%1\;and\t%0,0xff
- ldxb\t%0,%1"
+ {and\t%0,0xff|%0 &= 0xff}
+ {mov\t%0,%1\;and\t%0,0xff|%0 = %1;%0 &= 0xff}
+ {ldxh\t%0,%1|%0 = *(u8 *) %1}"
[(set_attr "type" "alu,alu,ldx")])
(define_insn "zero_extendsidi2"
@@ -277,8 +279,8 @@
(match_operand:SI 1 "nonimmediate_operand" "r,q")))]
""
"@
- * return bpf_has_alu32 ? \"mov32\t%0,%1\" : \"mov\t%0,%1\;and\t%0,0xffffffff\";
- ldxw\t%0,%1"
+ * return bpf_has_alu32 ? \"{mov32\t%0,%1|%0 = %1}\" : \"{mov\t%0,%1\;and\t%0,0xffffffff|%0 = %1;%0 &= 0xffffffff}\";
+ {ldxw\t%0,%1|%0 = *(u32 *) %1}"
[(set_attr "type" "alu,ldx")])
;;; Sign-extension
@@ -317,11 +319,11 @@
(match_operand:MM 1 "mov_src_operand" " q,rI,B,r,I"))]
""
"@
- ldx<mop>\t%0,%1
- mov\t%0,%1
- lddw\t%0,%1
- stx<mop>\t%0,%1
- st<mop>\t%0,%1"
+ {ldx<mop>\t%0,%1|%0 = *(<smop> *) %1}
+ {mov\t%0,%1|%0 = %1}
+ {lddw\t%0,%1|%0 = %1 ll}
+ {stx<mop>\t%0,%1|*(<smop> *) %0 = %1}
+ {st<mop>\t%0,%1|*(<smop> *) %0 = %1}"
[(set_attr "type" "ldx,alu,alu,stx,st")])
;;;; Shifts
@@ -333,7 +335,7 @@
(ashiftrt:SIM (match_operand:SIM 1 "register_operand" " 0,0")
(match_operand:SIM 2 "reg_or_imm_operand" " r,I")))]
""
- "arsh<msuffix>\t%0,%2"
+ "{arsh<msuffix>\t%0,%2|%w0 s>>= %w2}"
[(set_attr "type" "<mtype>")])
(define_insn "ashl<SIM:mode>3"
@@ -341,7 +343,7 @@
(ashift:SIM (match_operand:SIM 1 "register_operand" " 0,0")
(match_operand:SIM 2 "reg_or_imm_operand" " r,I")))]
""
- "lsh<msuffix>\t%0,%2"
+ "{lsh<msuffix>\t%0,%2|%w0 <<= %w2}"
[(set_attr "type" "<mtype>")])
(define_insn "lshr<SIM:mode>3"
@@ -349,7 +351,7 @@
(lshiftrt:SIM (match_operand:SIM 1 "register_operand" " 0,0")
(match_operand:SIM 2 "reg_or_imm_operand" " r,I")))]
""
- "rsh<msuffix>\t%0,%2"
+ "{rsh<msuffix>\t%0,%2|%w0 >>= %w2}"
[(set_attr "type" "<mtype>")])
;;;; Endianness conversion
@@ -363,9 +365,9 @@
""
{
if (TARGET_BIG_ENDIAN)
- return "endle\t%0, <endmode>";
+ return "{endle\t%0, <endmode>|%0 = le<endmode> %0}";
else
- return "endbe\t%0, <endmode>";
+ return "{endbe\t%0, <endmode>|%0 = be<endmode> %0}";
}
[(set_attr "type" "end")])
@@ -404,16 +406,16 @@
switch (code)
{
- case EQ: return "jeq<msuffix>\t%0,%1,%2"; break;
- case NE: return "jne<msuffix>\t%0,%1,%2"; break;
- case LT: return "jslt<msuffix>\t%0,%1,%2"; break;
- case LE: return "jsle<msuffix>\t%0,%1,%2"; break;
- case GT: return "jsgt<msuffix>\t%0,%1,%2"; break;
- case GE: return "jsge<msuffix>\t%0,%1,%2"; break;
- case LTU: return "jlt<msuffix>\t%0,%1,%2"; break;
- case LEU: return "jle<msuffix>\t%0,%1,%2"; break;
- case GTU: return "jgt<msuffix>\t%0,%1,%2"; break;
- case GEU: return "jge<msuffix>\t%0,%1,%2"; break;
+ case EQ: return "{jeq<msuffix>\t%0,%1,%2|if %w0 == %w1 goto %2}"; break;
+ case NE: return "{jne<msuffix>\t%0,%1,%2|if %w0 != %w1 goto %2}"; break;
+ case LT: return "{jslt<msuffix>\t%0,%1,%2|if %w0 s< %w1 goto %2}"; break;
+ case LE: return "{jsle<msuffix>\t%0,%1,%2|if %w0 s<= %w1 goto %2}"; break;
+ case GT: return "{jsgt<msuffix>\t%0,%1,%2|if %w0 s> %w1 goto %2}"; break;
+ case GE: return "{jsge<msuffix>\t%0,%1,%2|if %w0 s>= %w1 goto %2}"; break;
+ case LTU: return "{jlt<msuffix>\t%0,%1,%2|if %w0 < %w1 goto %2}"; break;
+ case LEU: return "{jle<msuffix>\t%0,%1,%2|if %w0 <= %w1 goto %2}"; break;
+ case GTU: return "{jgt<msuffix>\t%0,%1,%2|if %w0 > %w1 goto %2}"; break;
+ case GEU: return "{jge<msuffix>\t%0,%1,%2|if %w0 >= %w1 goto %2}"; break;
default:
gcc_unreachable ();
return "";
@@ -427,7 +429,7 @@
[(set (pc)
(label_ref (match_operand 0 "" "")))]
""
- "ja\t%0"
+ "{ja\t%0|goto %0}"
[(set_attr "type" "jmp")])
;;;; Function prologue/epilogue
@@ -506,13 +508,14 @@
;; operands[2] is next_arg_register
;; operands[3] is struct_value_size_rtx.
""
- "ja\t%0"
+ "{ja\t%0|goto %0}"
[(set_attr "type" "jmp")])
;;;; Non-generic load instructions
(define_mode_iterator LDM [QI HI SI DI])
(define_mode_attr ldop [(QI "b") (HI "h") (SI "w") (DI "dw")])
+(define_mode_attr pldop [(QI "u8") (HI "u16") (SI "u32") (DI "u64")])
(define_insn "ldind<ldop>"
[(set (reg:LDM R0_REGNUM)
@@ -524,7 +527,7 @@
(clobber (reg:DI R3_REGNUM))
(clobber (reg:DI R4_REGNUM))]
""
- "ldind<ldop>\t%0,%1"
+ "{ldind<ldop>\t%0,%1|r0 = *(<pldop> *) skb[%0 + %1]}"
[(set_attr "type" "ld")])
(define_insn "ldabs<ldop>"
@@ -537,7 +540,7 @@
(clobber (reg:DI R3_REGNUM))
(clobber (reg:DI R4_REGNUM))]
""
- "ldabs<ldop>\t%0"
+ "{ldabs<ldop>\t%0|r0 = *(<pldop> *) skb[%0]}"
[(set_attr "type" "ld")])
;;;; Atomic increments
@@ -552,5 +555,5 @@
(match_operand:SI 2 "const_int_operand")] ;; Memory model.
UNSPEC_XADD))]
""
- "xadd<mop>\t%0,%1"
+ "{xadd<mop>\t%0,%1|*(<smop> *) %0 += %1}"
[(set_attr "type" "xadd")])
diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt
index fe3ad35..ff805f9 100644
--- a/gcc/config/bpf/bpf.opt
+++ b/gcc/config/bpf/bpf.opt
@@ -160,3 +160,17 @@ Enum(bpf_isa) String(v2) Value(ISA_V2)
EnumValue
Enum(bpf_isa) String(v3) Value(ISA_V3)
+
+masm=
+Target RejectNegative Joined Var(asm_dialect) Enum(asm_dialect) Init(ASM_NORMAL)
+Use given assembler dialect.
+
+Enum
+Name(asm_dialect) Type(enum bpf_asm_dialect)
+Known assembler dialects (for use with the -masm= option)
+
+EnumValue
+Enum(asm_dialect) String(normal) Value(ASM_NORMAL)
+
+EnumValue
+Enum(asm_dialect) String(pseudoc) Value(ASM_PSEUDOC)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 5628c08..efd356e 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -946,8 +946,8 @@ Objective-C and Objective-C++ Dialects}.
@emph{eBPF Options}
@gccoptlist{-mbig-endian -mlittle-endian -mkernel=@var{version}
--mframe-limit=@var{bytes} -mxbpf -mco-re -mno-co-re
--mjmpext -mjmp32 -malu32 -mcpu=@var{version}}
+-mframe-limit=@var{bytes} -mxbpf -mco-re -mno-co-re -mjmpext
+-mjmp32 -malu32 -mcpu=@var{version} -masm=@var{dialect}}
@emph{FR30 Options}
@gccoptlist{-msmall-model -mno-lsim}
@@ -24748,6 +24748,23 @@ the restrictions imposed by the BPF architecture:
@item Save and restore callee-saved registers at function entry and
exit, respectively.
@end itemize
+
+@opindex masm=@var{dialect}
+@item -masm=@var{dialect}
+Outputs assembly instructions using eBPF selected @var{dialect}. The default
+is @samp{normal}.
+
+Supported values for @var{dialect} are:
+
+@table @samp
+@item normal
+Outputs normal assembly dialect.
+
+@item pseudoc
+Outputs pseudo-c assembly dialect.
+
+@end table
+
@end table
@node FR30 Options