diff options
Diffstat (limited to 'gcc/config/bpf/bpf.cc')
-rw-r--r-- | gcc/config/bpf/bpf.cc | 89 |
1 files changed, 61 insertions, 28 deletions
diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc index fb60770c170..dd1bfe38d29 100644 --- a/gcc/config/bpf/bpf.cc +++ b/gcc/config/bpf/bpf.cc @@ -192,7 +192,8 @@ bpf_option_override (void) init_machine_status = bpf_init_machine_status; /* BPF CO-RE support requires BTF debug info generation. */ - if (TARGET_BPF_CORE && !btf_debuginfo_p ()) + if (TARGET_BPF_CORE + && (!btf_debuginfo_p () || (debug_info_level < DINFO_LEVEL_NORMAL))) error ("BPF CO-RE requires BTF debugging information, use %<-gbtf%>"); /* BPF applications always generate .BTF.ext. */ @@ -215,7 +216,9 @@ bpf_option_override (void) /* -gbtf implies -mcore when using the BPF backend, unless -mno-co-re is specified. */ - if (btf_debuginfo_p () && !(target_flags_explicit & MASK_BPF_CORE)) + if (btf_debuginfo_p () + && (debug_info_level >= DINFO_LEVEL_NORMAL) + && !(target_flags_explicit & MASK_BPF_CORE)) target_flags |= MASK_BPF_CORE; /* Determine available features from ISA setting (-mcpu=). */ @@ -284,23 +287,6 @@ bpf_file_end (void) #undef TARGET_ASM_FILE_END #define TARGET_ASM_FILE_END bpf_file_end -/* Define target-specific CPP macros. This function in used in the - definition of TARGET_CPU_CPP_BUILTINS in bpf.h */ - -#define builtin_define(TXT) cpp_define (pfile, TXT) - -void -bpf_target_macros (cpp_reader *pfile) -{ - builtin_define ("__BPF__"); - builtin_define ("__bpf__"); - - if (TARGET_BIG_ENDIAN) - builtin_define ("__BPF_BIG_ENDIAN__"); - else - builtin_define ("__BPF_LITTLE_ENDIAN__"); -} - /* Return an RTX representing the place where a function returns or receives a value of data type RET_TYPE, a tree node representing a data type. */ @@ -584,6 +570,16 @@ bpf_legitimate_address_p (machine_mode mode, if (bpf_address_base_p (x0, strict) && GET_CODE (x1) == CONST_INT) return IN_RANGE (INTVAL (x1), -1 - 0x7fff, 0x7fff); + /* Check if any of the PLUS operation operands is a CORE unspec, and at + least the local value for the offset fits in the 16 bits available + in the encoding. */ + if (bpf_address_base_p (x1, strict) + && GET_CODE (x0) == UNSPEC && XINT (x0, 1) == UNSPEC_CORE_RELOC) + return IN_RANGE (INTVAL (XVECEXP (x0, 0, 0)), -1 - 0x7fff, 0x7fff); + if (bpf_address_base_p (x0, strict) + && GET_CODE (x1) == UNSPEC && XINT (x1, 1) == UNSPEC_CORE_RELOC) + return IN_RANGE (INTVAL (XVECEXP (x1, 0, 0)), -1 - 0x7fff, 0x7fff); + break; } default: @@ -615,6 +611,21 @@ bpf_rtx_costs (rtx x ATTRIBUTE_UNUSED, #undef TARGET_RTX_COSTS #define TARGET_RTX_COSTS bpf_rtx_costs +static int +bpf_insn_cost (rtx_insn *insn, bool speed ATTRIBUTE_UNUSED) +{ + rtx pat = PATTERN (insn); + if(GET_CODE (pat) == SET + && GET_CODE (XEXP (pat, 1)) == UNSPEC + && XINT (XEXP (pat, 1), 1) == UNSPEC_CORE_RELOC) + return COSTS_N_INSNS (100); + + return COSTS_N_INSNS (1); +} + +#undef TARGET_INSN_COST +#define TARGET_INSN_COST bpf_insn_cost + /* Return true if an argument at the position indicated by CUM should be passed by reference. If the hook returns true, a copy of that argument is made in memory and a pointer to the argument is passed @@ -771,6 +782,13 @@ bpf_output_call (rtx target) return ""; } +const char * +bpf_output_move (rtx *operands, const char *templ) +{ + bpf_output_core_reloc (operands, 2); + return templ; +} + /* Print register name according to assembly dialect. In normal syntax registers are printed like %rN where N is the register number. @@ -852,6 +870,12 @@ bpf_print_operand (FILE *file, rtx op, int code) gcc_unreachable (); } break; + case UNSPEC: + if (XINT (op, 1) == UNSPEC_CORE_RELOC) + bpf_print_operand (file, XVECEXP (op, 0, 0), code); + else + gcc_unreachable (); + break; default: output_addr_const (file, op); } @@ -870,25 +894,33 @@ bpf_print_operand_address (FILE *file, rtx addr) switch (GET_CODE (addr)) { case REG: - if (asm_dialect == ASM_NORMAL) - fprintf (file, "["); + fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "("); bpf_print_register (file, addr, 0); - fprintf (file, asm_dialect == ASM_NORMAL ? "+0]" : "+0"); + fprintf (file, asm_dialect == ASM_NORMAL ? "+0]" : "+0)"); break; case PLUS: { rtx op0 = XEXP (addr, 0); rtx op1 = XEXP (addr, 1); - if (GET_CODE (op0) == REG && GET_CODE (op1) == CONST_INT) + if (GET_CODE (op1) == REG) { + op0 = op1; + op1 = XEXP (addr, 0); + } + + if (GET_CODE (op0) == REG + && (GET_CODE (op1) == CONST_INT + || (GET_CODE (op1) == UNSPEC + && XINT (op1, 1) == UNSPEC_CORE_RELOC))) { - if (asm_dialect == ASM_NORMAL) - fprintf (file, "["); + fprintf (file, asm_dialect == ASM_NORMAL ? "[" : "("); bpf_print_register (file, op0, 0); fprintf (file, "+"); - output_addr_const (file, op1); - if (asm_dialect == ASM_NORMAL) - fprintf (file, "]"); + if (GET_CODE (op1) == UNSPEC) + output_addr_const (file, XVECEXP (op1, 0, 0)); + else + output_addr_const (file, op1); + fprintf (file, asm_dialect == ASM_NORMAL ? "]" : ")"); } else fatal_insn ("invalid address in operand", addr); @@ -962,6 +994,7 @@ bpf_init_builtins (void) build_function_type_list (integer_type_node,integer_type_node, 0)); DECL_PURE_P (bpf_builtins[BPF_BUILTIN_CORE_RELOC]) = 1; + TREE_NOTHROW (bpf_builtins[BPF_BUILTIN_CORE_RELOC]) = 1; bpf_init_core_builtins (); } |