aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/bpf/bpf.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/bpf/bpf.cc')
-rw-r--r--gcc/config/bpf/bpf.cc89
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 ();
}