ARMv8-M Security Extension's cmse_nonsecure_call: use __gnu_cmse_nonsecure_call
gcc/ChangeLog: 2016-12-02 Andre Vieira <andre.simoesdiasvieira@arm.com> Thomas Preud'homme <thomas.preudhomme@arm.com> * config/arm/arm.c (detect_cmse_nonsecure_call): New. (cmse_nonsecure_call_clear_caller_saved): New. (arm_reorg): Use cmse_nonsecure_call_clear_caller_saved. (arm_function_ok_for_sibcall): Disable sibcalls for cmse_nonsecure_call. * config/arm/arm-protos.h (detect_cmse_nonsecure_call): New. * config/arm/arm.md (call): Handle cmse_nonsecure_entry. (call_value): Likewise. (nonsecure_call_internal): New. (nonsecure_call_value_internal): New. * config/arm/thumb1.md (*nonsecure_call_reg_thumb1_v5): New. (*nonsecure_call_value_reg_thumb1_v5): New. * config/arm/thumb2.md (*nonsecure_call_reg_thumb2): New. (*nonsecure_call_value_reg_thumb2): New. * config/arm/unspecs.md (UNSPEC_NONSECURE_MEM): New. libgcc/ChangeLog: 2016-12-02 Andre Vieira <andre.simoesdiasvieira@arm.com> Thomas Preud'homme <thomas.preudhomme@arm.com> * config/arm/cmse_nonsecure_call.S: New. * config/arm/t-arm: Compile cmse_nonsecure_call.S gcc/testsuite/ChangeLog: 2016-12-02 Andre Vieira <andre.simoesdiasvieira@arm.com> Thomas Preud'homme <thomas.preudhomme@arm.com> * gcc.target/arm/cmse/cmse.exp: Run tests in mainline dir. * gcc.target/arm/cmse/cmse-9.c: Added some extra tests. * gcc.target/arm/cmse/cmse-14.c: New. * gcc.target/arm/cmse/baseline/bitfield-4.c: New. * gcc.target/arm/cmse/baseline/bitfield-5.c: New. * gcc.target/arm/cmse/baseline/bitfield-6.c: New. * gcc.target/arm/cmse/baseline/bitfield-7.c: New. * gcc.target/arm/cmse/baseline/bitfield-8.c: New. * gcc.target/arm/cmse/baseline/bitfield-9.c: New. * gcc.target/arm/cmse/baseline/bitfield-and-union-1.c: New. * gcc.target/arm/cmse/baseline/cmse-11.c: New. * gcc.target/arm/cmse/baseline/cmse-13.c: New. * gcc.target/arm/cmse/baseline/cmse-6.c: New. * gcc.target/arm/cmse/baseline/union-1.c: New. * gcc.target/arm/cmse/baseline/union-2.c: New. * gcc.target/arm/cmse/mainline/bitfield-4.c: New. * gcc.target/arm/cmse/mainline/bitfield-5.c: New. * gcc.target/arm/cmse/mainline/bitfield-6.c: New. * gcc.target/arm/cmse/mainline/bitfield-7.c: New. * gcc.target/arm/cmse/mainline/bitfield-8.c: New. * gcc.target/arm/cmse/mainline/bitfield-9.c: New. * gcc.target/arm/cmse/mainline/bitfield-and-union-1.c: New. * gcc.target/arm/cmse/mainline/union-1.c: New. * gcc.target/arm/cmse/mainline/union-2.c: New. * gcc.target/arm/cmse/mainline/hard-sp/cmse-13.c: New. * gcc.target/arm/cmse/mainline/hard-sp/cmse-7.c: New. * gcc.target/arm/cmse/mainline/hard-sp/cmse-8.c: New. * gcc.target/arm/cmse/mainline/hard/cmse-13.c: New. * gcc.target/arm/cmse/mainline/hard/cmse-7.c: New. * gcc.target/arm/cmse/mainline/hard/cmse-8.c: New. * gcc.target/arm/cmse/mainline/soft/cmse-13.c: New. * gcc.target/arm/cmse/mainline/soft/cmse-7.c: New. * gcc.target/arm/cmse/mainline/soft/cmse-8.c: New. * gcc.target/arm/cmse/mainline/softfp-sp/cmse-7.c: New. * gcc.target/arm/cmse/mainline/softfp-sp/cmse-8.c: New. * gcc.target/arm/cmse/mainline/softfp/cmse-13.c: New. * gcc.target/arm/cmse/mainline/softfp/cmse-7.c: New. * gcc.target/arm/cmse/mainline/softfp/cmse-8.c: New. Co-Authored-By: Thomas Preud'homme <thomas.preudhomme@arm.com> From-SVN: r243192
This commit is contained in:
parent
32ce1e4f24
commit
c92e08e3d7
49 changed files with 2238 additions and 6 deletions
|
@ -1,3 +1,22 @@
|
|||
2016-12-02 Andre Vieira <andre.simoesdiasvieira@arm.com>
|
||||
Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||
|
||||
* config/arm/arm.c (detect_cmse_nonsecure_call): New.
|
||||
(cmse_nonsecure_call_clear_caller_saved): New.
|
||||
(arm_reorg): Use cmse_nonsecure_call_clear_caller_saved.
|
||||
(arm_function_ok_for_sibcall): Disable sibcalls for
|
||||
cmse_nonsecure_call.
|
||||
* config/arm/arm-protos.h (detect_cmse_nonsecure_call): New.
|
||||
* config/arm/arm.md (call): Handle cmse_nonsecure_entry.
|
||||
(call_value): Likewise.
|
||||
(nonsecure_call_internal): New.
|
||||
(nonsecure_call_value_internal): New.
|
||||
* config/arm/thumb1.md (*nonsecure_call_reg_thumb1_v5): New.
|
||||
(*nonsecure_call_value_reg_thumb1_v5): New.
|
||||
* config/arm/thumb2.md (*nonsecure_call_reg_thumb2): New.
|
||||
(*nonsecure_call_value_reg_thumb2): New.
|
||||
* config/arm/unspecs.md (UNSPEC_NONSECURE_MEM): New.
|
||||
|
||||
2016-12-02 Andre Vieira <andre.simoesdiasvieira@arm.com>
|
||||
Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||
|
||||
|
|
|
@ -137,6 +137,7 @@ extern int arm_const_double_inline_cost (rtx);
|
|||
extern bool arm_const_double_by_parts (rtx);
|
||||
extern bool arm_const_double_by_immediates (rtx);
|
||||
extern void arm_emit_call_insn (rtx, rtx, bool);
|
||||
bool detect_cmse_nonsecure_call (tree);
|
||||
extern const char *output_call (rtx *);
|
||||
void arm_emit_movpair (rtx, rtx);
|
||||
extern const char *output_mov_long_double_arm_from_arm (rtx *);
|
||||
|
|
|
@ -7000,6 +7000,15 @@ arm_function_ok_for_sibcall (tree decl, tree exp)
|
|||
if (IS_CMSE_ENTRY (arm_current_func_type ()))
|
||||
return false;
|
||||
|
||||
/* We do not allow ARMv8-M non-secure calls to be turned into sibling calls,
|
||||
this would complicate matters for later code generation. */
|
||||
if (TREE_CODE (exp) == CALL_EXPR)
|
||||
{
|
||||
tree fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp)));
|
||||
if (lookup_attribute ("cmse_nonsecure_call", TYPE_ATTRIBUTES (fntype)))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!VOID_TYPE_P (TREE_TYPE (DECL_RESULT (cfun->decl))))
|
||||
{
|
||||
/* Check that the return value locations are the same. For
|
||||
|
@ -16654,6 +16663,197 @@ compute_not_to_clear_mask (tree arg_type, rtx arg_rtx, int regno,
|
|||
return not_to_clear_mask;
|
||||
}
|
||||
|
||||
/* Saves callee saved registers, clears callee saved registers and caller saved
|
||||
registers not used to pass arguments before a cmse_nonsecure_call. And
|
||||
restores the callee saved registers after. */
|
||||
|
||||
static void
|
||||
cmse_nonsecure_call_clear_caller_saved (void)
|
||||
{
|
||||
basic_block bb;
|
||||
|
||||
FOR_EACH_BB_FN (bb, cfun)
|
||||
{
|
||||
rtx_insn *insn;
|
||||
|
||||
FOR_BB_INSNS (bb, insn)
|
||||
{
|
||||
uint64_t to_clear_mask, float_mask;
|
||||
rtx_insn *seq;
|
||||
rtx pat, call, unspec, reg, cleared_reg, tmp;
|
||||
unsigned int regno, maxregno;
|
||||
rtx address;
|
||||
CUMULATIVE_ARGS args_so_far_v;
|
||||
cumulative_args_t args_so_far;
|
||||
tree arg_type, fntype;
|
||||
bool using_r4, first_param = true;
|
||||
function_args_iterator args_iter;
|
||||
uint32_t padding_bits_to_clear[4] = {0U, 0U, 0U, 0U};
|
||||
uint32_t * padding_bits_to_clear_ptr = &padding_bits_to_clear[0];
|
||||
|
||||
if (!NONDEBUG_INSN_P (insn))
|
||||
continue;
|
||||
|
||||
if (!CALL_P (insn))
|
||||
continue;
|
||||
|
||||
pat = PATTERN (insn);
|
||||
gcc_assert (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 0);
|
||||
call = XVECEXP (pat, 0, 0);
|
||||
|
||||
/* Get the real call RTX if the insn sets a value, ie. returns. */
|
||||
if (GET_CODE (call) == SET)
|
||||
call = SET_SRC (call);
|
||||
|
||||
/* Check if it is a cmse_nonsecure_call. */
|
||||
unspec = XEXP (call, 0);
|
||||
if (GET_CODE (unspec) != UNSPEC
|
||||
|| XINT (unspec, 1) != UNSPEC_NONSECURE_MEM)
|
||||
continue;
|
||||
|
||||
/* Determine the caller-saved registers we need to clear. */
|
||||
to_clear_mask = (1LL << (NUM_ARG_REGS)) - 1;
|
||||
maxregno = NUM_ARG_REGS - 1;
|
||||
/* Only look at the caller-saved floating point registers in case of
|
||||
-mfloat-abi=hard. For -mfloat-abi=softfp we will be using the
|
||||
lazy store and loads which clear both caller- and callee-saved
|
||||
registers. */
|
||||
if (TARGET_HARD_FLOAT_ABI)
|
||||
{
|
||||
float_mask = (1LL << (D7_VFP_REGNUM + 1)) - 1;
|
||||
float_mask &= ~((1LL << FIRST_VFP_REGNUM) - 1);
|
||||
to_clear_mask |= float_mask;
|
||||
maxregno = D7_VFP_REGNUM;
|
||||
}
|
||||
|
||||
/* Make sure the register used to hold the function address is not
|
||||
cleared. */
|
||||
address = RTVEC_ELT (XVEC (unspec, 0), 0);
|
||||
gcc_assert (MEM_P (address));
|
||||
gcc_assert (REG_P (XEXP (address, 0)));
|
||||
to_clear_mask &= ~(1LL << REGNO (XEXP (address, 0)));
|
||||
|
||||
/* Set basic block of call insn so that df rescan is performed on
|
||||
insns inserted here. */
|
||||
set_block_for_insn (insn, bb);
|
||||
df_set_flags (DF_DEFER_INSN_RESCAN);
|
||||
start_sequence ();
|
||||
|
||||
/* Make sure the scheduler doesn't schedule other insns beyond
|
||||
here. */
|
||||
emit_insn (gen_blockage ());
|
||||
|
||||
/* Walk through all arguments and clear registers appropriately.
|
||||
*/
|
||||
fntype = TREE_TYPE (MEM_EXPR (address));
|
||||
arm_init_cumulative_args (&args_so_far_v, fntype, NULL_RTX,
|
||||
NULL_TREE);
|
||||
args_so_far = pack_cumulative_args (&args_so_far_v);
|
||||
FOREACH_FUNCTION_ARGS (fntype, arg_type, args_iter)
|
||||
{
|
||||
rtx arg_rtx;
|
||||
machine_mode arg_mode = TYPE_MODE (arg_type);
|
||||
|
||||
if (VOID_TYPE_P (arg_type))
|
||||
continue;
|
||||
|
||||
if (!first_param)
|
||||
arm_function_arg_advance (args_so_far, arg_mode, arg_type,
|
||||
true);
|
||||
|
||||
arg_rtx = arm_function_arg (args_so_far, arg_mode, arg_type,
|
||||
true);
|
||||
gcc_assert (REG_P (arg_rtx));
|
||||
to_clear_mask
|
||||
&= ~compute_not_to_clear_mask (arg_type, arg_rtx,
|
||||
REGNO (arg_rtx),
|
||||
padding_bits_to_clear_ptr);
|
||||
|
||||
first_param = false;
|
||||
}
|
||||
|
||||
/* Clear padding bits where needed. */
|
||||
cleared_reg = XEXP (address, 0);
|
||||
reg = gen_rtx_REG (SImode, IP_REGNUM);
|
||||
using_r4 = false;
|
||||
for (regno = R0_REGNUM; regno < NUM_ARG_REGS; regno++)
|
||||
{
|
||||
if (padding_bits_to_clear[regno] == 0)
|
||||
continue;
|
||||
|
||||
/* If this is a Thumb-1 target copy the address of the function
|
||||
we are calling from 'r4' into 'ip' such that we can use r4 to
|
||||
clear the unused bits in the arguments. */
|
||||
if (TARGET_THUMB1 && !using_r4)
|
||||
{
|
||||
using_r4 = true;
|
||||
reg = cleared_reg;
|
||||
emit_move_insn (gen_rtx_REG (SImode, IP_REGNUM),
|
||||
reg);
|
||||
}
|
||||
|
||||
tmp = GEN_INT ((((~padding_bits_to_clear[regno]) << 16u) >> 16u));
|
||||
emit_move_insn (reg, tmp);
|
||||
/* Also fill the top half of the negated
|
||||
padding_bits_to_clear. */
|
||||
if (((~padding_bits_to_clear[regno]) >> 16) > 0)
|
||||
{
|
||||
tmp = GEN_INT ((~padding_bits_to_clear[regno]) >> 16);
|
||||
emit_insn (gen_rtx_SET (gen_rtx_ZERO_EXTRACT (SImode, reg,
|
||||
GEN_INT (16),
|
||||
GEN_INT (16)),
|
||||
tmp));
|
||||
}
|
||||
|
||||
emit_insn (gen_andsi3 (gen_rtx_REG (SImode, regno),
|
||||
gen_rtx_REG (SImode, regno),
|
||||
reg));
|
||||
|
||||
}
|
||||
if (using_r4)
|
||||
emit_move_insn (cleared_reg,
|
||||
gen_rtx_REG (SImode, IP_REGNUM));
|
||||
|
||||
/* We use right shift and left shift to clear the LSB of the address
|
||||
we jump to instead of using bic, to avoid having to use an extra
|
||||
register on Thumb-1. */
|
||||
tmp = gen_rtx_LSHIFTRT (SImode, cleared_reg, const1_rtx);
|
||||
emit_insn (gen_rtx_SET (cleared_reg, tmp));
|
||||
tmp = gen_rtx_ASHIFT (SImode, cleared_reg, const1_rtx);
|
||||
emit_insn (gen_rtx_SET (cleared_reg, tmp));
|
||||
|
||||
/* Clearing all registers that leak before doing a non-secure
|
||||
call. */
|
||||
for (regno = R0_REGNUM; regno <= maxregno; regno++)
|
||||
{
|
||||
if (!(to_clear_mask & (1LL << regno)))
|
||||
continue;
|
||||
|
||||
/* If regno is an even vfp register and its successor is also to
|
||||
be cleared, use vmov. */
|
||||
if (IS_VFP_REGNUM (regno))
|
||||
{
|
||||
if (TARGET_VFP_DOUBLE
|
||||
&& VFP_REGNO_OK_FOR_DOUBLE (regno)
|
||||
&& to_clear_mask & (1LL << (regno + 1)))
|
||||
emit_move_insn (gen_rtx_REG (DFmode, regno++),
|
||||
CONST0_RTX (DFmode));
|
||||
else
|
||||
emit_move_insn (gen_rtx_REG (SFmode, regno),
|
||||
CONST0_RTX (SFmode));
|
||||
}
|
||||
else
|
||||
emit_move_insn (gen_rtx_REG (SImode, regno), cleared_reg);
|
||||
}
|
||||
|
||||
seq = get_insns ();
|
||||
end_sequence ();
|
||||
emit_insn_before (seq, insn);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Rewrite move insn into subtract of 0 if the condition codes will
|
||||
be useful in next conditional jump insn. */
|
||||
|
||||
|
@ -16954,6 +17154,8 @@ arm_reorg (void)
|
|||
HOST_WIDE_INT address = 0;
|
||||
Mfix * fix;
|
||||
|
||||
if (use_cmse)
|
||||
cmse_nonsecure_call_clear_caller_saved ();
|
||||
if (TARGET_THUMB1)
|
||||
thumb1_reorg ();
|
||||
else if (TARGET_THUMB2)
|
||||
|
@ -17326,6 +17528,23 @@ vfp_emit_fstmd (int base_reg, int count)
|
|||
return count * 8;
|
||||
}
|
||||
|
||||
/* Returns true if -mcmse has been passed and the function pointed to by 'addr'
|
||||
has the cmse_nonsecure_call attribute and returns false otherwise. */
|
||||
|
||||
bool
|
||||
detect_cmse_nonsecure_call (tree addr)
|
||||
{
|
||||
if (!addr)
|
||||
return FALSE;
|
||||
|
||||
tree fntype = TREE_TYPE (addr);
|
||||
if (use_cmse && lookup_attribute ("cmse_nonsecure_call",
|
||||
TYPE_ATTRIBUTES (fntype)))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Emit a call instruction with pattern PAT. ADDR is the address of
|
||||
the call target. */
|
||||
|
||||
|
|
|
@ -8052,6 +8052,7 @@
|
|||
"
|
||||
{
|
||||
rtx callee, pat;
|
||||
tree addr = MEM_EXPR (operands[0]);
|
||||
|
||||
/* In an untyped call, we can get NULL for operand 2. */
|
||||
if (operands[2] == NULL_RTX)
|
||||
|
@ -8066,8 +8067,17 @@
|
|||
: !REG_P (callee))
|
||||
XEXP (operands[0], 0) = force_reg (Pmode, callee);
|
||||
|
||||
pat = gen_call_internal (operands[0], operands[1], operands[2]);
|
||||
arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
|
||||
if (detect_cmse_nonsecure_call (addr))
|
||||
{
|
||||
pat = gen_nonsecure_call_internal (operands[0], operands[1],
|
||||
operands[2]);
|
||||
emit_call_insn (pat);
|
||||
}
|
||||
else
|
||||
{
|
||||
pat = gen_call_internal (operands[0], operands[1], operands[2]);
|
||||
arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
|
||||
}
|
||||
DONE;
|
||||
}"
|
||||
)
|
||||
|
@ -8078,6 +8088,24 @@
|
|||
(use (match_operand 2 "" ""))
|
||||
(clobber (reg:SI LR_REGNUM))])])
|
||||
|
||||
(define_expand "nonsecure_call_internal"
|
||||
[(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
|
||||
UNSPEC_NONSECURE_MEM)
|
||||
(match_operand 1 "general_operand" ""))
|
||||
(use (match_operand 2 "" ""))
|
||||
(clobber (reg:SI LR_REGNUM))
|
||||
(clobber (reg:SI 4))])]
|
||||
"use_cmse"
|
||||
"
|
||||
{
|
||||
rtx tmp;
|
||||
tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
|
||||
gen_rtx_REG (SImode, 4),
|
||||
SImode);
|
||||
|
||||
operands[0] = replace_equiv_address (operands[0], tmp);
|
||||
}")
|
||||
|
||||
(define_insn "*call_reg_armv5"
|
||||
[(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
|
||||
(match_operand 1 "" ""))
|
||||
|
@ -8113,6 +8141,7 @@
|
|||
"
|
||||
{
|
||||
rtx pat, callee;
|
||||
tree addr = MEM_EXPR (operands[1]);
|
||||
|
||||
/* In an untyped call, we can get NULL for operand 2. */
|
||||
if (operands[3] == 0)
|
||||
|
@ -8127,9 +8156,18 @@
|
|||
: !REG_P (callee))
|
||||
XEXP (operands[1], 0) = force_reg (Pmode, callee);
|
||||
|
||||
pat = gen_call_value_internal (operands[0], operands[1],
|
||||
operands[2], operands[3]);
|
||||
arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
|
||||
if (detect_cmse_nonsecure_call (addr))
|
||||
{
|
||||
pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
|
||||
operands[2], operands[3]);
|
||||
emit_call_insn (pat);
|
||||
}
|
||||
else
|
||||
{
|
||||
pat = gen_call_value_internal (operands[0], operands[1],
|
||||
operands[2], operands[3]);
|
||||
arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
|
||||
}
|
||||
DONE;
|
||||
}"
|
||||
)
|
||||
|
@ -8141,6 +8179,25 @@
|
|||
(use (match_operand 3 "" ""))
|
||||
(clobber (reg:SI LR_REGNUM))])])
|
||||
|
||||
(define_expand "nonsecure_call_value_internal"
|
||||
[(parallel [(set (match_operand 0 "" "")
|
||||
(call (unspec:SI [(match_operand 1 "memory_operand" "")]
|
||||
UNSPEC_NONSECURE_MEM)
|
||||
(match_operand 2 "general_operand" "")))
|
||||
(use (match_operand 3 "" ""))
|
||||
(clobber (reg:SI LR_REGNUM))
|
||||
(clobber (reg:SI 4))])]
|
||||
"use_cmse"
|
||||
"
|
||||
{
|
||||
rtx tmp;
|
||||
tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
|
||||
gen_rtx_REG (SImode, 4),
|
||||
SImode);
|
||||
|
||||
operands[1] = replace_equiv_address (operands[1], tmp);
|
||||
}")
|
||||
|
||||
(define_insn "*call_value_reg_armv5"
|
||||
[(set (match_operand 0 "" "")
|
||||
(call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
|
||||
|
|
|
@ -1731,6 +1731,19 @@
|
|||
(set_attr "type" "call")]
|
||||
)
|
||||
|
||||
(define_insn "*nonsecure_call_reg_thumb1_v5"
|
||||
[(call (unspec:SI [(mem:SI (match_operand:SI 0 "register_operand" "l*r"))]
|
||||
UNSPEC_NONSECURE_MEM)
|
||||
(match_operand 1 "" ""))
|
||||
(use (match_operand 2 "" ""))
|
||||
(clobber (reg:SI LR_REGNUM))
|
||||
(clobber (match_dup 0))]
|
||||
"TARGET_THUMB1 && use_cmse && !SIBLING_CALL_P (insn)"
|
||||
"bl\\t__gnu_cmse_nonsecure_call"
|
||||
[(set_attr "length" "4")
|
||||
(set_attr "type" "call")]
|
||||
)
|
||||
|
||||
(define_insn "*call_reg_thumb1"
|
||||
[(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
|
||||
(match_operand 1 "" ""))
|
||||
|
@ -1763,6 +1776,21 @@
|
|||
(set_attr "type" "call")]
|
||||
)
|
||||
|
||||
(define_insn "*nonsecure_call_value_reg_thumb1_v5"
|
||||
[(set (match_operand 0 "" "")
|
||||
(call (unspec:SI
|
||||
[(mem:SI (match_operand:SI 1 "register_operand" "l*r"))]
|
||||
UNSPEC_NONSECURE_MEM)
|
||||
(match_operand 2 "" "")))
|
||||
(use (match_operand 3 "" ""))
|
||||
(clobber (reg:SI LR_REGNUM))
|
||||
(clobber (match_dup 1))]
|
||||
"TARGET_THUMB1 && use_cmse"
|
||||
"bl\\t__gnu_cmse_nonsecure_call"
|
||||
[(set_attr "length" "4")
|
||||
(set_attr "type" "call")]
|
||||
)
|
||||
|
||||
(define_insn "*call_value_reg_thumb1"
|
||||
[(set (match_operand 0 "" "")
|
||||
(call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
|
||||
|
|
|
@ -580,6 +580,19 @@
|
|||
[(set_attr "type" "call")]
|
||||
)
|
||||
|
||||
(define_insn "*nonsecure_call_reg_thumb2"
|
||||
[(call (unspec:SI [(mem:SI (match_operand:SI 0 "s_register_operand" "r"))]
|
||||
UNSPEC_NONSECURE_MEM)
|
||||
(match_operand 1 "" ""))
|
||||
(use (match_operand 2 "" ""))
|
||||
(clobber (reg:SI LR_REGNUM))
|
||||
(clobber (match_dup 0))]
|
||||
"TARGET_THUMB2 && use_cmse"
|
||||
"bl\\t__gnu_cmse_nonsecure_call"
|
||||
[(set_attr "length" "4")
|
||||
(set_attr "type" "call")]
|
||||
)
|
||||
|
||||
(define_insn "*call_value_reg_thumb2"
|
||||
[(set (match_operand 0 "" "")
|
||||
(call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
|
||||
|
@ -591,6 +604,21 @@
|
|||
[(set_attr "type" "call")]
|
||||
)
|
||||
|
||||
(define_insn "*nonsecure_call_value_reg_thumb2"
|
||||
[(set (match_operand 0 "" "")
|
||||
(call
|
||||
(unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "l*r"))]
|
||||
UNSPEC_NONSECURE_MEM)
|
||||
(match_operand 2 "" "")))
|
||||
(use (match_operand 3 "" ""))
|
||||
(clobber (reg:SI LR_REGNUM))
|
||||
(clobber (match_dup 1))]
|
||||
"TARGET_THUMB2 && use_cmse"
|
||||
"bl\t__gnu_cmse_nonsecure_call"
|
||||
[(set_attr "length" "4")
|
||||
(set_attr "type" "call")]
|
||||
)
|
||||
|
||||
(define_insn "*thumb2_indirect_jump"
|
||||
[(set (pc)
|
||||
(match_operand:SI 0 "register_operand" "l*r"))]
|
||||
|
|
|
@ -84,6 +84,8 @@
|
|||
UNSPEC_VRINTA ; Represent a float to integral float rounding
|
||||
; towards nearest, ties away from zero.
|
||||
UNSPEC_PROBE_STACK ; Probe stack memory reference
|
||||
UNSPEC_NONSECURE_MEM ; Represent non-secure memory in ARMv8-M with
|
||||
; security extension
|
||||
])
|
||||
|
||||
(define_c_enum "unspec" [
|
||||
|
|
|
@ -1,3 +1,45 @@
|
|||
2016-12-02 Andre Vieira <andre.simoesdiasvieira@arm.com>
|
||||
Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||
|
||||
* gcc.target/arm/cmse/cmse.exp: Run tests in mainline dir.
|
||||
* gcc.target/arm/cmse/cmse-9.c: Added some extra tests.
|
||||
* gcc.target/arm/cmse/cmse-14.c: New.
|
||||
* gcc.target/arm/cmse/baseline/bitfield-4.c: New.
|
||||
* gcc.target/arm/cmse/baseline/bitfield-5.c: New.
|
||||
* gcc.target/arm/cmse/baseline/bitfield-6.c: New.
|
||||
* gcc.target/arm/cmse/baseline/bitfield-7.c: New.
|
||||
* gcc.target/arm/cmse/baseline/bitfield-8.c: New.
|
||||
* gcc.target/arm/cmse/baseline/bitfield-9.c: New.
|
||||
* gcc.target/arm/cmse/baseline/bitfield-and-union-1.c: New.
|
||||
* gcc.target/arm/cmse/baseline/cmse-11.c: New.
|
||||
* gcc.target/arm/cmse/baseline/cmse-13.c: New.
|
||||
* gcc.target/arm/cmse/baseline/cmse-6.c: New.
|
||||
* gcc.target/arm/cmse/baseline/union-1.c: New.
|
||||
* gcc.target/arm/cmse/baseline/union-2.c: New.
|
||||
* gcc.target/arm/cmse/mainline/bitfield-4.c: New.
|
||||
* gcc.target/arm/cmse/mainline/bitfield-5.c: New.
|
||||
* gcc.target/arm/cmse/mainline/bitfield-6.c: New.
|
||||
* gcc.target/arm/cmse/mainline/bitfield-7.c: New.
|
||||
* gcc.target/arm/cmse/mainline/bitfield-8.c: New.
|
||||
* gcc.target/arm/cmse/mainline/bitfield-9.c: New.
|
||||
* gcc.target/arm/cmse/mainline/bitfield-and-union-1.c: New.
|
||||
* gcc.target/arm/cmse/mainline/union-1.c: New.
|
||||
* gcc.target/arm/cmse/mainline/union-2.c: New.
|
||||
* gcc.target/arm/cmse/mainline/hard-sp/cmse-13.c: New.
|
||||
* gcc.target/arm/cmse/mainline/hard-sp/cmse-7.c: New.
|
||||
* gcc.target/arm/cmse/mainline/hard-sp/cmse-8.c: New.
|
||||
* gcc.target/arm/cmse/mainline/hard/cmse-13.c: New.
|
||||
* gcc.target/arm/cmse/mainline/hard/cmse-7.c: New.
|
||||
* gcc.target/arm/cmse/mainline/hard/cmse-8.c: New.
|
||||
* gcc.target/arm/cmse/mainline/soft/cmse-13.c: New.
|
||||
* gcc.target/arm/cmse/mainline/soft/cmse-7.c: New.
|
||||
* gcc.target/arm/cmse/mainline/soft/cmse-8.c: New.
|
||||
* gcc.target/arm/cmse/mainline/softfp-sp/cmse-7.c: New.
|
||||
* gcc.target/arm/cmse/mainline/softfp-sp/cmse-8.c: New.
|
||||
* gcc.target/arm/cmse/mainline/softfp/cmse-13.c: New.
|
||||
* gcc.target/arm/cmse/mainline/softfp/cmse-7.c: New.
|
||||
* gcc.target/arm/cmse/mainline/softfp/cmse-8.c: New.
|
||||
|
||||
2016-12-02 Andre Vieira <andre.simoesdiasvieira@arm.com>
|
||||
Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||
|
||||
|
|
57
gcc/testsuite/gcc.target/arm/cmse/baseline/bitfield-4.c
Normal file
57
gcc/testsuite/gcc.target/arm/cmse/baseline/bitfield-4.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned int b:5;
|
||||
unsigned int c:11, :0, d:8;
|
||||
struct { unsigned int ee:2; } e;
|
||||
} test_st;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st st;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_st;
|
||||
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_st);
|
||||
|
||||
extern void foo (test_st st);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_st r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
r.values.v2 = 0xFFFFFFFF;
|
||||
r.values.v3 = 0xFFFFFFFF;
|
||||
r.values.v4 = 0xFFFFFFFF;
|
||||
|
||||
f (r.st);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "mov\tip, r4" } } */
|
||||
/* { dg-final { scan-assembler "movw\tr4, #65535" } } */
|
||||
/* { dg-final { scan-assembler "movt\tr4, 255" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr4, #255" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr4, #3" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr4, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
53
gcc/testsuite/gcc.target/arm/cmse/baseline/bitfield-5.c
Normal file
53
gcc/testsuite/gcc.target/arm/cmse/baseline/bitfield-5.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned short b :5;
|
||||
unsigned char c;
|
||||
unsigned short d :11;
|
||||
} test_st;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st st;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_st;
|
||||
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_st);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_st r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
r.values.v2 = 0xFFFFFFFF;
|
||||
|
||||
f (r.st);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "mov\tip, r4" } } */
|
||||
/* { dg-final { scan-assembler "movw\tr4, #8191" } } */
|
||||
/* { dg-final { scan-assembler "movt\tr4, 255" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "movw\tr4, #2047" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr4, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
|
63
gcc/testsuite/gcc.target/arm/cmse/baseline/bitfield-6.c
Normal file
63
gcc/testsuite/gcc.target/arm/cmse/baseline/bitfield-6.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned int b : 3;
|
||||
unsigned int c : 14;
|
||||
unsigned int d : 1;
|
||||
struct {
|
||||
unsigned int ee : 2;
|
||||
unsigned short ff : 15;
|
||||
} e;
|
||||
unsigned char g : 1;
|
||||
unsigned char : 4;
|
||||
unsigned char h : 3;
|
||||
} test_st;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st st;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_st;
|
||||
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_st);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_st r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
r.values.v2 = 0xFFFFFFFF;
|
||||
r.values.v3 = 0xFFFFFFFF;
|
||||
r.values.v4 = 0xFFFFFFFF;
|
||||
|
||||
f (r.st);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "mov\tip, r4" } } */
|
||||
/* { dg-final { scan-assembler "movw\tr4, #65535" } } */
|
||||
/* { dg-final { scan-assembler "movt\tr4, 1023" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr4, #3" } } */
|
||||
/* { dg-final { scan-assembler "movt\tr4, 32767" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr4, #255" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr4, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
54
gcc/testsuite/gcc.target/arm/cmse/baseline/bitfield-7.c
Normal file
54
gcc/testsuite/gcc.target/arm/cmse/baseline/bitfield-7.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned short b :5;
|
||||
unsigned char c;
|
||||
unsigned short d :11;
|
||||
} test_st;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st st;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_st;
|
||||
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_st);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_st r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
r.values.v2 = 0xFFFFFFFF;
|
||||
|
||||
f (r.st);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* { dg-final { scan-assembler "mov\tip, r4" } } */
|
||||
/* { dg-final { scan-assembler "movw\tr4, #8191" } } */
|
||||
/* { dg-final { scan-assembler "movt\tr4, 255" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "movw\tr4, #2047" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr4, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
|
57
gcc/testsuite/gcc.target/arm/cmse/baseline/bitfield-8.c
Normal file
57
gcc/testsuite/gcc.target/arm/cmse/baseline/bitfield-8.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned int :0;
|
||||
unsigned int b :1;
|
||||
unsigned short :0;
|
||||
unsigned short c;
|
||||
unsigned int :0;
|
||||
unsigned int d :21;
|
||||
} test_st;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st st;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_st;
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_st);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_st r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
r.values.v2 = 0xFFFFFFFF;
|
||||
r.values.v3 = 0xFFFFFFFF;
|
||||
|
||||
f (r.st);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "mov\tip, r4" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr4, #255" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr4, #1" } } */
|
||||
/* { dg-final { scan-assembler "movt\tr4, 65535" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "movw\tr4, #65535" } } */
|
||||
/* { dg-final { scan-assembler "movt\tr4, 31" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr4, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
56
gcc/testsuite/gcc.target/arm/cmse/baseline/bitfield-9.c
Normal file
56
gcc/testsuite/gcc.target/arm/cmse/baseline/bitfield-9.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char a:3;
|
||||
} test_st3;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char a:3;
|
||||
} test_st2;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
test_st2 st2;
|
||||
test_st3 st3;
|
||||
} test_st;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st st;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_st;
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_st);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_st r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
|
||||
f (r.st);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "mov\tip, r4" } } */
|
||||
/* { dg-final { scan-assembler "movw\tr4, #1799" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr4, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
|
@ -0,0 +1,96 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short a :11;
|
||||
} test_st_4;
|
||||
|
||||
typedef union
|
||||
{
|
||||
char a;
|
||||
test_st_4 st4;
|
||||
}test_un_2;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned int :0;
|
||||
unsigned int b :1;
|
||||
unsigned short :0;
|
||||
unsigned short c;
|
||||
unsigned int :0;
|
||||
unsigned int d :21;
|
||||
} test_st_3;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a :3;
|
||||
unsigned int b :13;
|
||||
test_un_2 un2;
|
||||
} test_st_2;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st_2 st2;
|
||||
test_st_3 st3;
|
||||
}test_un_1;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a :2;
|
||||
unsigned char :0;
|
||||
unsigned short b :5;
|
||||
unsigned char :0;
|
||||
unsigned char c :4;
|
||||
test_un_1 un1;
|
||||
} test_st_1;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st_1 st1;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_st_1;
|
||||
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_st_1);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_st_1 r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
r.values.v2 = 0xFFFFFFFF;
|
||||
r.values.v3 = 0xFFFFFFFF;
|
||||
r.values.v4 = 0xFFFFFFFF;
|
||||
|
||||
f (r.st1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "mov\tip, r4" } } */
|
||||
/* { dg-final { scan-assembler "movw\tr4, #7939" } } */
|
||||
/* { dg-final { scan-assembler "movt\tr4, 15" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "movw\tr4, #65535" } } */
|
||||
/* { dg-final { scan-assembler "movt\tr4, 2047" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr4, #1" } } */
|
||||
/* { dg-final { scan-assembler "movt\tr4, 65535" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "movw\tr4, #65535" } } */
|
||||
/* { dg-final { scan-assembler "movt\tr4, 31" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr4, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
22
gcc/testsuite/gcc.target/arm/cmse/baseline/cmse-11.c
Normal file
22
gcc/testsuite/gcc.target/arm/cmse/baseline/cmse-11.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_base_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_base } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (int);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar (bar (a + 1));
|
||||
}
|
||||
|
||||
/* Checks for saving and clearing prior to function call. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr3, r4" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
25
gcc/testsuite/gcc.target/arm/cmse/baseline/cmse-13.c
Normal file
25
gcc/testsuite/gcc.target/arm/cmse/baseline/cmse-13.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_base_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_base } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (float, double);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar (1.0f, 2.0) + a + 1;
|
||||
}
|
||||
|
||||
/* Checks for saving and clearing prior to function call. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler-not "movs\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "\n\tmovs\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler-not "\n\tmovs\tr2, r4\n\tmovs\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler-not "vmov" } } */
|
||||
/* { dg-final { scan-assembler-not "vmsr" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
|
21
gcc/testsuite/gcc.target/arm/cmse/baseline/cmse-6.c
Normal file
21
gcc/testsuite/gcc.target/arm/cmse/baseline/cmse-6.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_base_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_base } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (double);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar (2.0) + a + 1;
|
||||
}
|
||||
|
||||
/* Remember dont clear r0 and r1, because we are passing the double parameter
|
||||
* for bar in them. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr2, r4" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
71
gcc/testsuite/gcc.target/arm/cmse/baseline/union-1.c
Normal file
71
gcc/testsuite/gcc.target/arm/cmse/baseline/union-1.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a :2;
|
||||
unsigned char :0;
|
||||
unsigned short b :5;
|
||||
unsigned char :0;
|
||||
unsigned short c :3;
|
||||
unsigned char :0;
|
||||
unsigned int d :9;
|
||||
} test_st_1;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short a :7;
|
||||
unsigned char :0;
|
||||
unsigned char b :1;
|
||||
unsigned char :0;
|
||||
unsigned short c :6;
|
||||
} test_st_2;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st_1 st_1;
|
||||
test_st_2 st_2;
|
||||
}test_un;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_un un;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_un;
|
||||
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_un);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_un r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
r.values.v2 = 0xFFFFFFFF;
|
||||
|
||||
f (r.un);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "mov\tip, r4" } } */
|
||||
/* { dg-final { scan-assembler "movw\tr4, #8063" } } */
|
||||
/* { dg-final { scan-assembler "movt\tr4, 63" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "movw\tr4, #511" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr4, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
|
86
gcc/testsuite/gcc.target/arm/cmse/baseline/union-2.c
Normal file
86
gcc/testsuite/gcc.target/arm/cmse/baseline/union-2.c
Normal file
|
@ -0,0 +1,86 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a :2;
|
||||
unsigned char :0;
|
||||
unsigned short b :5;
|
||||
unsigned char :0;
|
||||
unsigned short c :3;
|
||||
unsigned char :0;
|
||||
unsigned int d :9;
|
||||
} test_st_1;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short a :7;
|
||||
unsigned char :0;
|
||||
unsigned char b :1;
|
||||
unsigned char :0;
|
||||
unsigned short c :6;
|
||||
} test_st_2;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned int :0;
|
||||
unsigned int b :1;
|
||||
unsigned short :0;
|
||||
unsigned short c;
|
||||
unsigned int :0;
|
||||
unsigned int d :21;
|
||||
} test_st_3;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st_1 st_1;
|
||||
test_st_2 st_2;
|
||||
test_st_3 st_3;
|
||||
}test_un;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_un un;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_un;
|
||||
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_un);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_un r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
r.values.v2 = 0xFFFFFFFF;
|
||||
r.values.v3 = 0xFFFFFFFF;
|
||||
|
||||
f (r.un);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "mov\tip, r4" } } */
|
||||
/* { dg-final { scan-assembler "movw\tr4, #8191" } } */
|
||||
/* { dg-final { scan-assembler "movt\tr4, 63" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "movw\tr4, #511" } } */
|
||||
/* { dg-final { scan-assembler "movt\tr4, 65535" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "movw\tr4, #65535" } } */
|
||||
/* { dg-final { scan-assembler "movt\tr4, 31" } } */
|
||||
/* { dg-final { scan-assembler "ands\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr4, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "movs\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
13
gcc/testsuite/gcc.target/arm/cmse/cmse-14.c
Normal file
13
gcc/testsuite/gcc.target/arm/cmse/cmse-14.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (void);
|
||||
|
||||
int foo (void)
|
||||
{
|
||||
return bar ();
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
/* { dg-final { scan-assembler-not "b\[^ y\n\]*\\s+bar" } } */
|
|
@ -2,11 +2,19 @@
|
|||
/* { dg-skip-if "Testing exclusion of -mcmse" { arm-*-* } { "-mcmse" } { "" } } */
|
||||
|
||||
|
||||
void __attribute__ ((cmse_nonsecure_call)) (*bar) (int); /* { dg-warning "attribute ignored without -mcmse option" } */
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) baz (int); /* { dg-warning "attribute ignored without -mcmse option" } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_entry))
|
||||
foo (int a)
|
||||
foo (int a, baz b)
|
||||
{ /* { dg-warning "attribute ignored without -mcmse option" } */
|
||||
bar (a);
|
||||
b (a);
|
||||
return a + 1;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "bxns" } } */
|
||||
/* { dg-final { scan-assembler-not "blxns" } } */
|
||||
/* { dg-final { scan-assembler-not "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
/* { dg-final { scan-assembler "foo:" } } */
|
||||
/* { dg-final { scan-assembler-not "__acle_se_foo:" } } */
|
||||
|
|
|
@ -50,6 +50,8 @@ if {[check_effective_target_arm_arch_v8m_base_ok]} then {
|
|||
}
|
||||
|
||||
if {[check_effective_target_arm_arch_v8m_main_ok]} then {
|
||||
gcc-dg-runtest [lsort [glob $srcdir/$subdir/mainline/*.c]] \
|
||||
"" $DEFAULT_CFLAGS
|
||||
# Mainline -mfloat-abi=soft
|
||||
gcc-dg-runtest [lsort [glob $srcdir/$subdir/mainline/soft/*.c]] \
|
||||
"-mfloat-abi=soft" $DEFAULT_CFLAGS
|
||||
|
|
55
gcc/testsuite/gcc.target/arm/cmse/mainline/bitfield-4.c
Normal file
55
gcc/testsuite/gcc.target/arm/cmse/mainline/bitfield-4.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned int b:5;
|
||||
unsigned int c:11, :0, d:8;
|
||||
struct { unsigned int ee:2; } e;
|
||||
} test_st;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st st;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_st;
|
||||
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_st);
|
||||
|
||||
extern void foo (test_st st);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_st r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
r.values.v2 = 0xFFFFFFFF;
|
||||
r.values.v3 = 0xFFFFFFFF;
|
||||
r.values.v4 = 0xFFFFFFFF;
|
||||
|
||||
f (r.st);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "movw\tip, #65535" } } */
|
||||
/* { dg-final { scan-assembler "movt\tip, 255" } } */
|
||||
/* { dg-final { scan-assembler "and\tr0, r0, ip" } } */
|
||||
/* { dg-final { scan-assembler "mov\tip, #255" } } */
|
||||
/* { dg-final { scan-assembler "and\tr1, r1, ip" } } */
|
||||
/* { dg-final { scan-assembler "mov\tip, #3" } } */
|
||||
/* { dg-final { scan-assembler "and\tr2, r2, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
51
gcc/testsuite/gcc.target/arm/cmse/mainline/bitfield-5.c
Normal file
51
gcc/testsuite/gcc.target/arm/cmse/mainline/bitfield-5.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned short b :5;
|
||||
unsigned char c;
|
||||
unsigned short d :11;
|
||||
} test_st;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st st;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_st;
|
||||
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_st);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_st r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
r.values.v2 = 0xFFFFFFFF;
|
||||
|
||||
f (r.st);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "movw\tip, #8191" } } */
|
||||
/* { dg-final { scan-assembler "movt\tip, 255" } } */
|
||||
/* { dg-final { scan-assembler "and\tr0, r0, ip" } } */
|
||||
/* { dg-final { scan-assembler "movw\tip, #2047" } } */
|
||||
/* { dg-final { scan-assembler "and\tr1, r1, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
|
61
gcc/testsuite/gcc.target/arm/cmse/mainline/bitfield-6.c
Normal file
61
gcc/testsuite/gcc.target/arm/cmse/mainline/bitfield-6.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned int b : 3;
|
||||
unsigned int c : 14;
|
||||
unsigned int d : 1;
|
||||
struct {
|
||||
unsigned int ee : 2;
|
||||
unsigned short ff : 15;
|
||||
} e;
|
||||
unsigned char g : 1;
|
||||
unsigned char : 4;
|
||||
unsigned char h : 3;
|
||||
} test_st;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st st;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_st;
|
||||
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_st);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_st r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
r.values.v2 = 0xFFFFFFFF;
|
||||
r.values.v3 = 0xFFFFFFFF;
|
||||
r.values.v4 = 0xFFFFFFFF;
|
||||
|
||||
f (r.st);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "movw\tip, #65535" } } */
|
||||
/* { dg-final { scan-assembler "movt\tip, 1023" } } */
|
||||
/* { dg-final { scan-assembler "and\tr0, r0, ip" } } */
|
||||
/* { dg-final { scan-assembler "mov\tip, #3" } } */
|
||||
/* { dg-final { scan-assembler "movt\tip, 32767" } } */
|
||||
/* { dg-final { scan-assembler "and\tr1, r1, ip" } } */
|
||||
/* { dg-final { scan-assembler "mov\tip, #255" } } */
|
||||
/* { dg-final { scan-assembler "and\tr2, r2, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
52
gcc/testsuite/gcc.target/arm/cmse/mainline/bitfield-7.c
Normal file
52
gcc/testsuite/gcc.target/arm/cmse/mainline/bitfield-7.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned short b :5;
|
||||
unsigned char c;
|
||||
unsigned short d :11;
|
||||
} test_st;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st st;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_st;
|
||||
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_st);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_st r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
r.values.v2 = 0xFFFFFFFF;
|
||||
|
||||
f (r.st);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* { dg-final { scan-assembler "movw\tip, #8191" } } */
|
||||
/* { dg-final { scan-assembler "movt\tip, 255" } } */
|
||||
/* { dg-final { scan-assembler "and\tr0, r0, ip" } } */
|
||||
/* { dg-final { scan-assembler "movw\tip, #2047" } } */
|
||||
/* { dg-final { scan-assembler "and\tr1, r1, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
|
55
gcc/testsuite/gcc.target/arm/cmse/mainline/bitfield-8.c
Normal file
55
gcc/testsuite/gcc.target/arm/cmse/mainline/bitfield-8.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned int :0;
|
||||
unsigned int b :1;
|
||||
unsigned short :0;
|
||||
unsigned short c;
|
||||
unsigned int :0;
|
||||
unsigned int d :21;
|
||||
} test_st;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st st;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_st;
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_st);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_st r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
r.values.v2 = 0xFFFFFFFF;
|
||||
r.values.v3 = 0xFFFFFFFF;
|
||||
|
||||
f (r.st);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "mov\tip, #255" } } */
|
||||
/* { dg-final { scan-assembler "and\tr0, r0, ip" } } */
|
||||
/* { dg-final { scan-assembler "mov\tip, #1" } } */
|
||||
/* { dg-final { scan-assembler "movt\tip, 65535" } } */
|
||||
/* { dg-final { scan-assembler "and\tr1, r1, ip" } } */
|
||||
/* { dg-final { scan-assembler "movw\tip, #65535" } } */
|
||||
/* { dg-final { scan-assembler "movt\tip, 31" } } */
|
||||
/* { dg-final { scan-assembler "and\tr2, r2, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
54
gcc/testsuite/gcc.target/arm/cmse/mainline/bitfield-9.c
Normal file
54
gcc/testsuite/gcc.target/arm/cmse/mainline/bitfield-9.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char a:3;
|
||||
} test_st3;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char a:3;
|
||||
} test_st2;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
test_st2 st2;
|
||||
test_st3 st3;
|
||||
} test_st;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st st;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_st;
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_st);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_st r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
|
||||
f (r.st);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "movw\tip, #1799" } } */
|
||||
/* { dg-final { scan-assembler "and\tr0, r0, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
|
@ -0,0 +1,94 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short a :11;
|
||||
} test_st_4;
|
||||
|
||||
typedef union
|
||||
{
|
||||
char a;
|
||||
test_st_4 st4;
|
||||
}test_un_2;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned int :0;
|
||||
unsigned int b :1;
|
||||
unsigned short :0;
|
||||
unsigned short c;
|
||||
unsigned int :0;
|
||||
unsigned int d :21;
|
||||
} test_st_3;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a :3;
|
||||
unsigned int b :13;
|
||||
test_un_2 un2;
|
||||
} test_st_2;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st_2 st2;
|
||||
test_st_3 st3;
|
||||
}test_un_1;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a :2;
|
||||
unsigned char :0;
|
||||
unsigned short b :5;
|
||||
unsigned char :0;
|
||||
unsigned char c :4;
|
||||
test_un_1 un1;
|
||||
} test_st_1;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st_1 st1;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_st_1;
|
||||
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_st_1);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_st_1 r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
r.values.v2 = 0xFFFFFFFF;
|
||||
r.values.v3 = 0xFFFFFFFF;
|
||||
r.values.v4 = 0xFFFFFFFF;
|
||||
|
||||
f (r.st1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "movw\tip, #7939" } } */
|
||||
/* { dg-final { scan-assembler "movt\tip, 15" } } */
|
||||
/* { dg-final { scan-assembler "and\tr0, r0, ip" } } */
|
||||
/* { dg-final { scan-assembler "movw\tip, #65535" } } */
|
||||
/* { dg-final { scan-assembler "movt\tip, 2047" } } */
|
||||
/* { dg-final { scan-assembler "and\tr1, r1, ip" } } */
|
||||
/* { dg-final { scan-assembler "mov\tip, #1" } } */
|
||||
/* { dg-final { scan-assembler "movt\tip, 65535" } } */
|
||||
/* { dg-final { scan-assembler "and\tr2, r2, ip" } } */
|
||||
/* { dg-final { scan-assembler "movw\tip, #65535" } } */
|
||||
/* { dg-final { scan-assembler "movt\tip, 31" } } */
|
||||
/* { dg-final { scan-assembler "and\tr3, r3, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
43
gcc/testsuite/gcc.target/arm/cmse/mainline/hard-sp/cmse-13.c
Normal file
43
gcc/testsuite/gcc.target/arm/cmse/mainline/hard-sp/cmse-13.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_main_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_main } */
|
||||
/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" {*-*-*} {"-mfloat-abi=soft" -mfloat-abi=softfp } {""} } */
|
||||
/* { dg-skip-if "Skip these if testing double precision" {*-*-*} {"-mfpu=fpv[4-5]-d16"} {""} } */
|
||||
/* { dg-options "-mcmse -mfloat-abi=hard -mfpu=fpv5-sp-d16" } */
|
||||
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (float, double);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar (3.0f, 2.0) + a + 1;
|
||||
}
|
||||
|
||||
/* Checks for saving and clearing prior to function call. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler-not "vldr\.32\ts0, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts1, .L" } } */
|
||||
/* { dg-final { scan-assembler-not "vldr\.32\ts2, .L" } } */
|
||||
/* { dg-final { scan-assembler-not "vldr\.32\ts3, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts4, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts5, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts6, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts7, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts8, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts9, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts10, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts11, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts12, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts13, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts14, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts15, .L" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
|
42
gcc/testsuite/gcc.target/arm/cmse/mainline/hard-sp/cmse-7.c
Normal file
42
gcc/testsuite/gcc.target/arm/cmse/mainline/hard-sp/cmse-7.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_main_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_main } */
|
||||
/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" {*-*-*} {"-mfloat-abi=soft" -mfloat-abi=softfp } {""} } */
|
||||
/* { dg-skip-if "Skip these if testing double precision" {*-*-*} {"-mfpu=fpv[4-5]-d16"} {""} } */
|
||||
/* { dg-options "-mcmse -mfloat-abi=hard -mfpu=fpv5-sp-d16" } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (void);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar () + a + 1;
|
||||
}
|
||||
|
||||
/* Checks for saving and clearing prior to function call. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts0, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts1, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts2, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts3, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts4, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts5, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts6, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts7, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts8, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts9, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts10, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts11, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts12, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts13, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts14, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts15, .L" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
|
41
gcc/testsuite/gcc.target/arm/cmse/mainline/hard-sp/cmse-8.c
Normal file
41
gcc/testsuite/gcc.target/arm/cmse/mainline/hard-sp/cmse-8.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_main_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_main } */
|
||||
/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" {*-*-*} {"-mfloat-abi=soft" -mfloat-abi=softfp } {""} } */
|
||||
/* { dg-skip-if "Skip these if testing double precision" {*-*-*} {"-mfpu=fpv[4-5]-d16"} {""} } */
|
||||
/* { dg-options "-mcmse -mfloat-abi=hard -mfpu=fpv5-sp-d16" } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (double);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar (2.0) + a + 1;
|
||||
}
|
||||
|
||||
/* Checks for saving and clearing prior to function call. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler-not "vldr\.32\ts0, .L" } } */
|
||||
/* { dg-final { scan-assembler-not "vldr\.32\ts1, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts2, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts3, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts4, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts5, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts6, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts7, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts8, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts9, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts10, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts11, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts12, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts13, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts14, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts15, .L" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
38
gcc/testsuite/gcc.target/arm/cmse/mainline/hard/cmse-13.c
Normal file
38
gcc/testsuite/gcc.target/arm/cmse/mainline/hard/cmse-13.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_main_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_main } */
|
||||
/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" {*-*-*} {"-mfloat-abi=soft" -mfloat-abi=softfp } {""} } */
|
||||
/* { dg-skip-if "Skip these if testing single precision" {*-*-*} {"-mfpu=*-sp-*"} {""} } */
|
||||
/* { dg-options "-mcmse -mfloat-abi=hard -mfpu=fpv5-d16" } */
|
||||
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (float, double);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar (3.0f, 2.0) + a + 1;
|
||||
}
|
||||
|
||||
/* Checks for saving and clearing prior to function call. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.32\ts1, .L" } } */
|
||||
/* { dg-final { scan-assembler-not "vldr\.64\td0, .L" } } */
|
||||
/* { dg-final { scan-assembler-not "vldr\.32\ts0, .L" } } */
|
||||
/* { dg-final { scan-assembler-not "vldr\.64\td1, .L" } } */
|
||||
/* { dg-final { scan-assembler-not "vldr\.32\ts2, .L" } } */
|
||||
/* { dg-final { scan-assembler-not "vldr\.32\ts3, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td2, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td3, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td4, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td5, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td6, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td7, .L" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
34
gcc/testsuite/gcc.target/arm/cmse/mainline/hard/cmse-7.c
Normal file
34
gcc/testsuite/gcc.target/arm/cmse/mainline/hard/cmse-7.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_main_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_main } */
|
||||
/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" {*-*-*} {"-mfloat-abi=soft" -mfloat-abi=softfp } {""} } */
|
||||
/* { dg-skip-if "Skip these if testing single precision" {*-*-*} {"-mfpu=*-sp-*"} {""} } */
|
||||
/* { dg-options "-mcmse -mfloat-abi=hard -mfpu=fpv5-d16" } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (void);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar () + a + 1;
|
||||
}
|
||||
|
||||
/* Checks for saving and clearing prior to function call. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td0, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td1, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td2, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td3, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td4, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td5, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td6, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td7, .L" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
|
33
gcc/testsuite/gcc.target/arm/cmse/mainline/hard/cmse-8.c
Normal file
33
gcc/testsuite/gcc.target/arm/cmse/mainline/hard/cmse-8.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_main_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_main } */
|
||||
/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" {*-*-*} {"-mfloat-abi=soft" -mfloat-abi=softfp } {""} } */
|
||||
/* { dg-skip-if "Skip these if testing single precision" {*-*-*} {"-mfpu=*-sp-*"} {""} } */
|
||||
/* { dg-options "-mcmse -mfloat-abi=hard -mfpu=fpv5-d16" } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (double);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar (2.0) + a + 1;
|
||||
}
|
||||
|
||||
/* Checks for saving and clearing prior to function call. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler-not "vldr\.64\td0, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td1, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td2, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td3, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td4, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td5, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td6, .L" } } */
|
||||
/* { dg-final { scan-assembler "vldr\.64\td7, .L" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
27
gcc/testsuite/gcc.target/arm/cmse/mainline/soft/cmse-13.c
Normal file
27
gcc/testsuite/gcc.target/arm/cmse/mainline/soft/cmse-13.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_main_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_main } */
|
||||
/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" {*-*-*} {"-mfloat-abi=hard" -mfloat-abi=softfp } {""} } */
|
||||
/* { dg-options "-mcmse -mfloat-abi=soft" } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (float, double);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar (1.0f, 2.0) + a + 1;
|
||||
}
|
||||
|
||||
/* Checks for saving and clearing prior to function call. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler-not "mov\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler-not "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler-not "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler-not "vmov" } } */
|
||||
/* { dg-final { scan-assembler-not "vmsr" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
|
27
gcc/testsuite/gcc.target/arm/cmse/mainline/soft/cmse-7.c
Normal file
27
gcc/testsuite/gcc.target/arm/cmse/mainline/soft/cmse-7.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_main_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_main } */
|
||||
/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" {*-*-*} {"-mfloat-abi=hard" -mfloat-abi=softfp } {""} } */
|
||||
/* { dg-options "-mcmse -mfloat-abi=soft" } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (void);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar () + a + 1;
|
||||
}
|
||||
|
||||
/* Checks for saving and clearing prior to function call. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler-not "vmov" } } */
|
||||
/* { dg-final { scan-assembler-not "vmsr" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
|
26
gcc/testsuite/gcc.target/arm/cmse/mainline/soft/cmse-8.c
Normal file
26
gcc/testsuite/gcc.target/arm/cmse/mainline/soft/cmse-8.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_main_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_main } */
|
||||
/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" {*-*-*} {"-mfloat-abi=hard" -mfloat-abi=softfp } {""} } */
|
||||
/* { dg-options "-mcmse -mfloat-abi=soft" } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (double);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar (2.0) + a + 1;
|
||||
}
|
||||
|
||||
/* Checks for saving and clearing prior to function call. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler-not "mov\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler-not "mov\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler-not "vmov" } } */
|
||||
/* { dg-final { scan-assembler-not "vmsr" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
|
@ -0,0 +1,26 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_main_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_main } */
|
||||
/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" {*-*-*} {"-mfloat-abi=soft" -mfloat-abi=hard } {""} } */
|
||||
/* { dg-skip-if "Skip these if testing double precision" {*-*-*} {"-mfpu=fpv[4-5]-d16"} {""} } */
|
||||
/* { dg-options "-mcmse -mfloat-abi=softfp -mfpu=fpv5-sp-d16" } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (void);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar () + a + 1;
|
||||
}
|
||||
|
||||
/* Checks for saving and clearing prior to function call. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_main_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_main } */
|
||||
/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" {*-*-*} {"-mfloat-abi=soft" -mfloat-abi=hard } {""} } */
|
||||
/* { dg-skip-if "Skip these if testing double precision" {*-*-*} {"-mfpu=fpv[4-5]-d16"} {""} } */
|
||||
/* { dg-options "-mcmse -mfloat-abi=softfp -mfpu=fpv5-sp-d16" } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (double);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar (2.0) + a + 1;
|
||||
}
|
||||
|
||||
/* Checks for saving and clearing prior to function call. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler-not "mov\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler-not "mov\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
25
gcc/testsuite/gcc.target/arm/cmse/mainline/softfp/cmse-13.c
Normal file
25
gcc/testsuite/gcc.target/arm/cmse/mainline/softfp/cmse-13.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_main_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_main } */
|
||||
/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" {*-*-*} {"-mfloat-abi=soft" -mfloat-abi=hard } {""} } */
|
||||
/* { dg-skip-if "Skip these if testing single precision" {*-*-*} {"-mfpu=*-sp-*"} {""} } */
|
||||
/* { dg-options "-mcmse -mfloat-abi=softfp -mfpu=fpv5-d16" } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (float, double);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar (1.0f, 2.0) + a + 1;
|
||||
}
|
||||
|
||||
/* Checks for saving and clearing prior to function call. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler-not "mov\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "\n\tmov\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler-not "\n\tmov\tr2, r4\n\tmov\tr3, r4" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
|
26
gcc/testsuite/gcc.target/arm/cmse/mainline/softfp/cmse-7.c
Normal file
26
gcc/testsuite/gcc.target/arm/cmse/mainline/softfp/cmse-7.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_main_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_main } */
|
||||
/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" {*-*-*} {"-mfloat-abi=soft" -mfloat-abi=hard } {""} } */
|
||||
/* { dg-skip-if "Skip these if testing single precision" {*-*-*} {"-mfpu=*-sp-*"} {""} } */
|
||||
/* { dg-options "-mcmse -mfloat-abi=softfp -mfpu=fpv5-d16" } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (void);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar () + a + 1;
|
||||
}
|
||||
|
||||
/* Checks for saving and clearing prior to function call. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
|
25
gcc/testsuite/gcc.target/arm/cmse/mainline/softfp/cmse-8.c
Normal file
25
gcc/testsuite/gcc.target/arm/cmse/mainline/softfp/cmse-8.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm_arch_v8m_main_ok } */
|
||||
/* { dg-add-options arm_arch_v8m_main } */
|
||||
/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" {*-*-*} {"-mfloat-abi=soft" -mfloat-abi=hard } {""} } */
|
||||
/* { dg-skip-if "Skip these if testing single precision" {*-*-*} {"-mfpu=*-sp-*"} {""} } */
|
||||
/* { dg-options "-mcmse -mfloat-abi=softfp -mfpu=fpv5-d16" } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_call)) (*bar) (double);
|
||||
|
||||
int
|
||||
foo (int a)
|
||||
{
|
||||
return bar (2.0) + a + 1;
|
||||
}
|
||||
|
||||
/* Checks for saving and clearing prior to function call. */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler-not "mov\tr0, r4" } } */
|
||||
/* { dg-final { scan-assembler-not "mov\tr1, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
|
||||
/* Now we check that we use the correct intrinsic to call. */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
69
gcc/testsuite/gcc.target/arm/cmse/mainline/union-1.c
Normal file
69
gcc/testsuite/gcc.target/arm/cmse/mainline/union-1.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a :2;
|
||||
unsigned char :0;
|
||||
unsigned short b :5;
|
||||
unsigned char :0;
|
||||
unsigned short c :3;
|
||||
unsigned char :0;
|
||||
unsigned int d :9;
|
||||
} test_st_1;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short a :7;
|
||||
unsigned char :0;
|
||||
unsigned char b :1;
|
||||
unsigned char :0;
|
||||
unsigned short c :6;
|
||||
} test_st_2;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st_1 st_1;
|
||||
test_st_2 st_2;
|
||||
}test_un;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_un un;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_un;
|
||||
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_un);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_un r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
r.values.v2 = 0xFFFFFFFF;
|
||||
|
||||
f (r.un);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "movw\tip, #8063" } } */
|
||||
/* { dg-final { scan-assembler "movt\tip, 63" } } */
|
||||
/* { dg-final { scan-assembler "and\tr0, r0, ip" } } */
|
||||
/* { dg-final { scan-assembler "movw\tip, #511" } } */
|
||||
/* { dg-final { scan-assembler "and\tr1, r1, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr2, r4" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
||||
|
84
gcc/testsuite/gcc.target/arm/cmse/mainline/union-2.c
Normal file
84
gcc/testsuite/gcc.target/arm/cmse/mainline/union-2.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse" } */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a :2;
|
||||
unsigned char :0;
|
||||
unsigned short b :5;
|
||||
unsigned char :0;
|
||||
unsigned short c :3;
|
||||
unsigned char :0;
|
||||
unsigned int d :9;
|
||||
} test_st_1;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short a :7;
|
||||
unsigned char :0;
|
||||
unsigned char b :1;
|
||||
unsigned char :0;
|
||||
unsigned short c :6;
|
||||
} test_st_2;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned int :0;
|
||||
unsigned int b :1;
|
||||
unsigned short :0;
|
||||
unsigned short c;
|
||||
unsigned int :0;
|
||||
unsigned int d :21;
|
||||
} test_st_3;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_st_1 st_1;
|
||||
test_st_2 st_2;
|
||||
test_st_3 st_3;
|
||||
}test_un;
|
||||
|
||||
typedef union
|
||||
{
|
||||
test_un un;
|
||||
struct
|
||||
{
|
||||
unsigned int v1;
|
||||
unsigned int v2;
|
||||
unsigned int v3;
|
||||
unsigned int v4;
|
||||
}values;
|
||||
} read_un;
|
||||
|
||||
|
||||
typedef void __attribute__ ((cmse_nonsecure_call)) (*foo_ns) (test_un);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
read_un r;
|
||||
foo_ns f;
|
||||
|
||||
f = (foo_ns) 0x200000;
|
||||
r.values.v1 = 0xFFFFFFFF;
|
||||
r.values.v2 = 0xFFFFFFFF;
|
||||
r.values.v3 = 0xFFFFFFFF;
|
||||
|
||||
f (r.un);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "movw\tip, #8191" } } */
|
||||
/* { dg-final { scan-assembler "movt\tip, 63" } } */
|
||||
/* { dg-final { scan-assembler "and\tr0, r0, ip" } } */
|
||||
/* { dg-final { scan-assembler "movw\tip, #511" } } */
|
||||
/* { dg-final { scan-assembler "movt\tip, 65535" } } */
|
||||
/* { dg-final { scan-assembler "and\tr1, r1, ip" } } */
|
||||
/* { dg-final { scan-assembler "movw\tip, #65535" } } */
|
||||
/* { dg-final { scan-assembler "movt\tip, 31" } } */
|
||||
/* { dg-final { scan-assembler "and\tr2, r2, ip" } } */
|
||||
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
|
||||
/* { dg-final { scan-assembler "mov\tr3, r4" } } */
|
||||
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
|
|
@ -1,3 +1,9 @@
|
|||
2016-12-02 Andre Vieira <andre.simoesdiasvieira@arm.com>
|
||||
Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||
|
||||
* config/arm/cmse_nonsecure_call.S: New.
|
||||
* config/arm/t-arm: Compile cmse_nonsecure_call.S
|
||||
|
||||
2016-12-02 Andre Vieira <andre.simoesdiasvieira@arm.com>
|
||||
Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||
|
||||
|
|
131
libgcc/config/arm/cmse_nonsecure_call.S
Normal file
131
libgcc/config/arm/cmse_nonsecure_call.S
Normal file
|
@ -0,0 +1,131 @@
|
|||
/* CMSE wrapper function used to save, clear and restore callee saved registers
|
||||
for cmse_nonsecure_call's.
|
||||
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by ARM Ltd.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
.syntax unified
|
||||
.thumb
|
||||
.global __gnu_cmse_nonsecure_call
|
||||
__gnu_cmse_nonsecure_call:
|
||||
#if defined(__ARM_ARCH_8M_MAIN__)
|
||||
push {r5-r11,lr}
|
||||
mov r7, r4
|
||||
mov r8, r4
|
||||
mov r9, r4
|
||||
mov r10, r4
|
||||
mov r11, r4
|
||||
mov ip, r4
|
||||
|
||||
/* Save and clear callee-saved registers only if we are dealing with hard float
|
||||
ABI. The unused caller-saved registers have already been cleared by GCC
|
||||
generated code. */
|
||||
#ifdef __ARM_PCS_VFP
|
||||
vpush.f64 {d8-d15}
|
||||
mov r5, #0
|
||||
vmov d8, r5, r5
|
||||
#if __ARM_FP & 0x04
|
||||
vmov s18, s19, r5, r5
|
||||
vmov s20, s21, r5, r5
|
||||
vmov s22, s23, r5, r5
|
||||
vmov s24, s25, r5, r5
|
||||
vmov s26, s27, r5, r5
|
||||
vmov s28, s29, r5, r5
|
||||
vmov s30, s31, r5, r5
|
||||
#elif __ARM_FP & 0x08
|
||||
vmov.f64 d9, d8
|
||||
vmov.f64 d10, d8
|
||||
vmov.f64 d11, d8
|
||||
vmov.f64 d12, d8
|
||||
vmov.f64 d13, d8
|
||||
vmov.f64 d14, d8
|
||||
vmov.f64 d15, d8
|
||||
#else
|
||||
#error "Half precision implementation not supported."
|
||||
#endif
|
||||
/* Clear the cumulative exception-status bits (0-4,7) and the
|
||||
condition code bits (28-31) of the FPSCR. */
|
||||
vmrs r5, fpscr
|
||||
movw r6, #65376
|
||||
movt r6, #4095
|
||||
ands r5, r6
|
||||
vmsr fpscr, r5
|
||||
|
||||
/* We are not dealing with hard float ABI, so we can safely use the vlstm and
|
||||
vlldm instructions without needing to preserve the registers used for
|
||||
argument passing. */
|
||||
#else
|
||||
sub sp, sp, #0x88 /* Reserve stack space to save all floating point
|
||||
registers, including FPSCR. */
|
||||
vlstm sp /* Lazy store and clearance of d0-d16 and FPSCR. */
|
||||
#endif /* __ARM_PCS_VFP */
|
||||
|
||||
/* Make sure to clear the 'GE' bits of the APSR register if 32-bit SIMD
|
||||
instructions are available. */
|
||||
#if defined(__ARM_FEATURE_SIMD32)
|
||||
msr APSR_nzcvqg, r4
|
||||
#else
|
||||
msr APSR_nzcvq, r4
|
||||
#endif
|
||||
|
||||
mov r5, r4
|
||||
mov r6, r4
|
||||
blxns r4
|
||||
|
||||
#ifdef __ARM_PCS_VFP
|
||||
vpop.f64 {d8-d15}
|
||||
#else
|
||||
vlldm sp /* Lazy restore of d0-d16 and FPSCR. */
|
||||
add sp, sp, #0x88 /* Free space used to save floating point registers. */
|
||||
#endif /* __ARM_PCS_VFP */
|
||||
|
||||
pop {r5-r11, pc}
|
||||
|
||||
#elif defined (__ARM_ARCH_8M_BASE__)
|
||||
push {r5-r7, lr}
|
||||
mov r5, r8
|
||||
mov r6, r9
|
||||
mov r7, r10
|
||||
push {r5-r7}
|
||||
mov r5, r11
|
||||
push {r5}
|
||||
mov r5, r4
|
||||
mov r6, r4
|
||||
mov r7, r4
|
||||
mov r8, r4
|
||||
mov r9, r4
|
||||
mov r10, r4
|
||||
mov r11, r4
|
||||
mov ip, r4
|
||||
msr APSR_nzcvq, r4
|
||||
blxns r4
|
||||
pop {r5}
|
||||
mov r11, r5
|
||||
pop {r5-r7}
|
||||
mov r10, r7
|
||||
mov r9, r6
|
||||
mov r8, r5
|
||||
pop {r5-r7, pc}
|
||||
|
||||
#else
|
||||
#error "This should only be used for armv8-m base- and mainline."
|
||||
#endif
|
|
@ -12,4 +12,6 @@ libgcc-objects += cmse.o cmse_nonsecure_call.o
|
|||
|
||||
cmse.o: $(srcdir)/config/arm/cmse.c
|
||||
$(gcc_compile) -c $(CMSE_OPTS) $<
|
||||
cmse_nonsecure_call.o: $(srcdir)/config/arm/cmse_nonsecure_call.S
|
||||
$(gcc_compile) -c $<
|
||||
endif
|
||||
|
|
Loading…
Add table
Reference in a new issue