> gcc/ChangeLog: > > * config/bpf/bpf.opt: Added option -masm=<dialect>. > * config/bpf/bpf-opts.h: Likewize. > * config/bpf/bpf.cc: Changed it to conform with new pseudoc > dialect support. > * config/bpf/bpf.h: Likewise. > * config/bpf/bpf.md: Added pseudo-c templates. > * doc/invoke.texi: (-masm=DIALECT) New eBPF option item.
I think the ChangeLog could be made more useful, and the syntax of the last entry is not entirely right. I suggest something like: * config/bpf/bpf.opt: Added option -masm=<dialect>. * config/bpf/bpf-opts.h (enum bpf_asm_dialect): New type. * config/bpf/bpf.cc (bpf_print_register): New function. (bpf_print_register): Support pseudo-c syntax for registers. (bpf_print_operand_address): Likewise. * config/bpf/bpf.h (ASM_SPEC): handle -msasm. (ASSEMBLER_DIALECT): Define. * config/bpf/bpf.md: Added pseudo-c templates. * doc/invoke.texi (-masm=DIALECT): New eBPF option item. Please make sure to run the contrib/gcc-changelog/git_check-commit.py script. > --- > gcc/config/bpf/bpf-opts.h | 6 +++ > gcc/config/bpf/bpf.cc | 46 ++++++++++++++++--- > gcc/config/bpf/bpf.h | 5 +- > gcc/config/bpf/bpf.md | 97 ++++++++++++++++++++------------------- > gcc/config/bpf/bpf.opt | 14 ++++++ > gcc/doc/invoke.texi | 21 ++++++++- > 6 files changed, 133 insertions(+), 56 deletions(-) > > diff --git a/gcc/config/bpf/bpf-opts.h b/gcc/config/bpf/bpf-opts.h > index 8282351cf045..92db01ec4d54 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 e0324e1e0e08..1d3936871d60 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 344aca02d1bb..9561bf59b800 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 f6be0a212345..0b8f409db687 100644 > --- a/gcc/config/bpf/bpf.md > +++ b/gcc/config/bpf/bpf.md > @@ -77,6 +77,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 "")]) > > @@ -110,7 +112,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 > @@ -123,15 +125,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") > - (neg:AM (match_operand:AM 1 "register_operand" " 0")))] > + [(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" > + "{neg<msuffix>\t%0,%1|%w0 = -%w1}" > [(set_attr "type" "<mtype>")]) > > ;;; Multiplication > @@ -140,7 +142,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" > @@ -149,7 +151,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 > @@ -162,7 +164,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. > @@ -172,7 +174,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 > @@ -185,7 +187,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. > @@ -195,7 +197,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 > @@ -204,7 +206,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 > @@ -213,7 +215,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 > @@ -222,7 +224,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 > @@ -245,9 +247,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" > @@ -255,9 +257,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" > @@ -266,8 +268,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 > @@ -306,11 +308,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 > @@ -322,7 +324,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" > @@ -330,7 +332,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" > @@ -338,7 +340,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 > @@ -352,9 +354,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")]) > > @@ -393,16 +395,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 ""; > @@ -416,7 +418,7 @@ > [(set (pc) > (label_ref (match_operand 0 "" "")))] > "" > - "ja\t%0" > + "{ja\t%0|goto %0}" > [(set_attr "type" "jmp")]) > > ;;;; Function prologue/epilogue > @@ -495,13 +497,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) > @@ -513,7 +516,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>" > @@ -526,7 +529,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 > @@ -541,5 +544,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 fe3ad355e4bd..ff805f9e083c 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 3063e71c8906..b3be65d3efae 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} > @@ -24736,6 +24736,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