Skip to content

Commit 2e94764

Browse files
author
clyon
committed
[ARM] Add support for -mpure-code in thumb-1 (v6m)
This patch extends support for -mpure-code to all thumb-1 processors, by removing the need for MOVT. Symbol addresses are built using upper8_15, upper0_7, lower8_15 and lower0_7 relocations, and constants are built using sequences of movs/adds and lsls instructions. The extension of the *thumb1_movhf pattern uses always the same size (6) although it can emit a shorter sequence when possible. This is similar to what *arm32_movhf already does. CASE_VECTOR_PC_RELATIVE is now false with -mpure-code, to avoid generating invalid assembly code with differences from symbols from two different sections (the difference cannot be computed by the assembler). Tests pr45701-[12].c needed a small adjustment to avoid matching upper8_15 when looking for the r8 register. Test no-literal-pool.c is augmented with __fp16, so it now uses -mfp16-format=ieee. Test thumb1-Os-mult.c generates an inline code sequence with -mpure-code and computes the multiplication by using a sequence of add/shift rather than using the multiply instruction, so we skip it in presence of -mpure-code. With -mcpu=cortex-m0, the pure-code/no-literal-pool.c fails because code like: static char *p = "Hello World"; char * testchar () { return p + 4; } generates 2 indirections (I removed non-essential directives/code) .section .rodata .LC0: .ascii "Hello World\000" .data p: .word .LC0 .section .rodata .LC2: .word p .section .text,"0x20000006",%progbits testchar: push {r7, lr} add r7, sp, #0 movs r3, #:upper8_15:#.LC2 lsls r3, gcc-mirror#8 adds r3, #:upper0_7:#.LC2 lsls r3, gcc-mirror#8 adds r3, #:lower8_15:#.LC2 lsls r3, gcc-mirror#8 adds r3, #:lower0_7:#.LC2 ldr r3, [r3] ldr r3, [r3] adds r3, r3, gcc-mirror#4 movs r0, r3 mov sp, r7 @ sp needed pop {r7, pc} By contrast, when using -mcpu=cortex-m4, the code looks like: .section .rodata .LC0: .ascii "Hello World\000" .data p: .word .LC0 testchar: push {r7} add r7, sp, #0 movw r3, #:lower16:p movt r3, #:upper16:p ldr r3, [r3] adds r3, r3, gcc-mirror#4 mov r0, r3 mov sp, r7 pop {r7} bx lr I haven't found yet how to make code for cortex-m0 apply upper/lower relocations to "p" instead of .LC2. The current code looks functional, but could be improved. 2019-10-18 Christophe Lyon <[email protected]> gcc/ * config/arm/arm-protos.h (thumb1_gen_const_int): Add new prototype. * config/arm/arm.c (arm_option_check_internal): Remove restriction on MOVT for -mpure-code. (thumb1_gen_const_int): New function. (thumb1_legitimate_address_p): Support -mpure-code. (thumb1_rtx_costs): Likewise. (thumb1_size_rtx_costs): Likewise. (arm_thumb1_mi_thunk): Likewise. * config/arm/arm.h (CASE_VECTOR_PC_RELATIVE): Likewise. * config/arm/thumb1.md (thumb1_movsi_symbol_ref): New. (*thumb1_movhf): Support -mpure-code. gcc/testsuite/ * gcc.target/arm/pr45701-1.c: Adjust for -mpure-code. * gcc.target/arm/pr45701-2.c: Likewise. * gcc.target/arm/pure-code/no-literal-pool.c: Add tests for __fp16. * gcc.target/arm/pure-code/pure-code.exp: Remove thumb2 and movt conditions. * gcc.target/arm/thumb1-Os-mult.c: Skip if -mpure-code is used. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@279463 138bc75d-0d04-0410-961f-82ee72b054a4
1 parent 3081f59 commit 2e94764

File tree

12 files changed

+192
-30
lines changed

12 files changed

+192
-30
lines changed

gcc/ChangeLog

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
2019-12-17 Christophe Lyon <[email protected]>
2+
3+
* config/arm/arm-protos.h (thumb1_gen_const_int): Add new prototype.
4+
* config/arm/arm.c (arm_option_check_internal): Remove restriction
5+
on MOVT for -mpure-code.
6+
(thumb1_gen_const_int): New function.
7+
(thumb1_legitimate_address_p): Support -mpure-code.
8+
(thumb1_rtx_costs): Likewise.
9+
(thumb1_size_rtx_costs): Likewise.
10+
(arm_thumb1_mi_thunk): Likewise.
11+
* config/arm/arm.h (CASE_VECTOR_PC_RELATIVE): Likewise.
12+
* config/arm/thumb1.md (thumb1_movsi_symbol_ref): New.
13+
(*thumb1_movhf): Support -mpure-code.
14+
* doc/invoke.texi (-mpure-code): Remove restriction on MOVT.
15+
116
2019-12-17 Andrew Stubbs <[email protected]>
217

318
* tree-vect-loop.c (vect_create_epilog_for_reduction): Mention pr92772

gcc/config/arm/arm-protos.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ extern bool arm_small_register_classes_for_mode_p (machine_mode);
7171
extern int const_ok_for_arm (HOST_WIDE_INT);
7272
extern int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
7373
extern int const_ok_for_dimode_op (HOST_WIDE_INT, enum rtx_code);
74+
extern void thumb1_gen_const_int (rtx, HOST_WIDE_INT);
7475
extern int arm_split_constant (RTX_CODE, machine_mode, rtx,
7576
HOST_WIDE_INT, rtx, rtx, int);
7677
extern int legitimate_pic_operand_p (rtx);

gcc/config/arm/arm.c

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2893,13 +2893,18 @@ arm_option_check_internal (struct gcc_options *opts)
28932893
{
28942894
const char *flag = (target_pure_code ? "-mpure-code" :
28952895
"-mslow-flash-data");
2896+
bool common_unsupported_modes = arm_arch_notm || flag_pic || TARGET_NEON;
28962897

2897-
/* We only support -mpure-code and -mslow-flash-data on M-profile targets
2898-
with MOVT. */
2899-
if (!TARGET_HAVE_MOVT || arm_arch_notm || flag_pic || TARGET_NEON)
2898+
/* We only support -mslow-flash-data on M-profile targets with
2899+
MOVT. */
2900+
if (target_slow_flash_data && (!TARGET_HAVE_MOVT || common_unsupported_modes))
29002901
error ("%s only supports non-pic code on M-profile targets with the "
29012902
"MOVT instruction", flag);
29022903

2904+
/* We only support -mpure-code on M-profile targets. */
2905+
if (target_pure_code && common_unsupported_modes)
2906+
error ("%s only supports non-pic code on M-profile targets", flag);
2907+
29032908
/* Cannot load addresses: -mslow-flash-data forbids literal pool and
29042909
-mword-relocations forbids relocation of MOVT/MOVW. */
29052910
if (target_word_relocations)
@@ -4421,6 +4426,38 @@ const_ok_for_dimode_op (HOST_WIDE_INT i, enum rtx_code code)
44214426
}
44224427
}
44234428

4429+
/* Emit a sequence of movs/adds/shift to produce a 32-bit constant.
4430+
Avoid generating useless code when one of the bytes is zero. */
4431+
void
4432+
thumb1_gen_const_int (rtx op0, HOST_WIDE_INT op1)
4433+
{
4434+
bool mov_done_p = false;
4435+
int i;
4436+
4437+
/* Emit upper 3 bytes if needed. */
4438+
for (i = 0; i < 3; i++)
4439+
{
4440+
int byte = (op1 >> (8 * (3 - i))) & 0xff;
4441+
4442+
if (byte)
4443+
{
4444+
emit_set_insn (op0, mov_done_p
4445+
? gen_rtx_PLUS (SImode,op0, GEN_INT (byte))
4446+
: GEN_INT (byte));
4447+
mov_done_p = true;
4448+
}
4449+
4450+
if (mov_done_p)
4451+
emit_set_insn (op0, gen_rtx_ASHIFT (SImode, op0, GEN_INT (8)));
4452+
}
4453+
4454+
/* Emit lower byte if needed. */
4455+
if (!mov_done_p)
4456+
emit_set_insn (op0, GEN_INT (op1 & 0xff));
4457+
else if (op1 & 0xff)
4458+
emit_set_insn (op0, gen_rtx_PLUS (SImode, op0, GEN_INT (op1 & 0xff)));
4459+
}
4460+
44244461
/* Emit a sequence of insns to handle a large constant.
44254462
CODE is the code of the operation required, it can be any of SET, PLUS,
44264463
IOR, AND, XOR, MINUS;
@@ -8576,7 +8613,8 @@ thumb1_legitimate_address_p (machine_mode mode, rtx x, int strict_p)
85768613
/* This is PC relative data before arm_reorg runs. */
85778614
else if (GET_MODE_SIZE (mode) >= 4 && CONSTANT_P (x)
85788615
&& GET_CODE (x) == SYMBOL_REF
8579-
&& CONSTANT_POOL_ADDRESS_P (x) && !flag_pic)
8616+
&& CONSTANT_POOL_ADDRESS_P (x) && !flag_pic
8617+
&& !arm_disable_literal_pool)
85808618
return 1;
85818619

85828620
/* This is PC relative data after arm_reorg runs. */
@@ -8644,6 +8682,7 @@ thumb1_legitimate_address_p (machine_mode mode, rtx x, int strict_p)
86448682
&& GET_MODE_SIZE (mode) == 4
86458683
&& GET_CODE (x) == SYMBOL_REF
86468684
&& CONSTANT_POOL_ADDRESS_P (x)
8685+
&& !arm_disable_literal_pool
86478686
&& ! (flag_pic
86488687
&& symbol_mentioned_p (get_pool_constant (x))
86498688
&& ! pcrel_constant_p (get_pool_constant (x))))
@@ -9322,7 +9361,9 @@ thumb1_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
93229361
return 0;
93239362
if (thumb_shiftable_const (INTVAL (x)))
93249363
return COSTS_N_INSNS (2);
9325-
return COSTS_N_INSNS (3);
9364+
return arm_disable_literal_pool
9365+
? COSTS_N_INSNS (8)
9366+
: COSTS_N_INSNS (3);
93269367
}
93279368
else if ((outer == PLUS || outer == COMPARE)
93289369
&& INTVAL (x) < 256 && INTVAL (x) > -256)
@@ -9479,7 +9520,9 @@ thumb1_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
94799520
/* See split "TARGET_THUMB1 && satisfies_constraint_K". */
94809521
if (thumb_shiftable_const (INTVAL (x)))
94819522
return COSTS_N_INSNS (2);
9482-
return COSTS_N_INSNS (3);
9523+
return arm_disable_literal_pool
9524+
? COSTS_N_INSNS (8)
9525+
: COSTS_N_INSNS (3);
94839526
}
94849527
else if ((outer == PLUS || outer == COMPARE)
94859528
&& INTVAL (x) < 256 && INTVAL (x) > -256)
@@ -27465,14 +27508,41 @@ arm_thumb1_mi_thunk (FILE *file, tree, HOST_WIDE_INT delta,
2746527508
/* push r3 so we can use it as a temporary. */
2746627509
/* TODO: Omit this save if r3 is not used. */
2746727510
fputs ("\tpush {r3}\n", file);
27468-
fputs ("\tldr\tr3, ", file);
27511+
27512+
/* With -mpure-code, we cannot load the address from the
27513+
constant pool: we build it explicitly. */
27514+
if (target_pure_code)
27515+
{
27516+
fputs ("\tmovs\tr3, #:upper8_15:#", file);
27517+
assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
27518+
fputc ('\n', file);
27519+
fputs ("\tlsls r3, #8\n", file);
27520+
fputs ("\tadds\tr3, #:upper0_7:#", file);
27521+
assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
27522+
fputc ('\n', file);
27523+
fputs ("\tlsls r3, #8\n", file);
27524+
fputs ("\tadds\tr3, #:lower8_15:#", file);
27525+
assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
27526+
fputc ('\n', file);
27527+
fputs ("\tlsls r3, #8\n", file);
27528+
fputs ("\tadds\tr3, #:lower0_7:#", file);
27529+
assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
27530+
fputc ('\n', file);
27531+
}
27532+
else
27533+
fputs ("\tldr\tr3, ", file);
2746927534
}
2747027535
else
2747127536
{
2747227537
fputs ("\tldr\tr12, ", file);
2747327538
}
27474-
assemble_name (file, label);
27475-
fputc ('\n', file);
27539+
27540+
if (!target_pure_code)
27541+
{
27542+
assemble_name (file, label);
27543+
fputc ('\n', file);
27544+
}
27545+
2747627546
if (flag_pic)
2747727547
{
2747827548
/* If we are generating PIC, the ldr instruction below loads

gcc/config/arm/arm.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1857,9 +1857,11 @@ enum arm_auto_incmodes
18571857
for the index in the tablejump instruction. */
18581858
#define CASE_VECTOR_MODE Pmode
18591859

1860-
#define CASE_VECTOR_PC_RELATIVE (TARGET_THUMB2 \
1861-
|| (TARGET_THUMB1 \
1862-
&& (optimize_size || flag_pic)))
1860+
#define CASE_VECTOR_PC_RELATIVE ((TARGET_THUMB2 \
1861+
|| (TARGET_THUMB1 \
1862+
&& (optimize_size || flag_pic))) \
1863+
&& (!target_pure_code))
1864+
18631865

18641866
#define CASE_VECTOR_SHORTEN_MODE(min, max, body) \
18651867
(TARGET_THUMB1 \

gcc/config/arm/thumb1.md

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,41 @@
4343

4444

4545

46+
(define_insn "thumb1_movsi_symbol_ref"
47+
[(set (match_operand:SI 0 "register_operand" "=l")
48+
(match_operand:SI 1 "general_operand" ""))
49+
]
50+
"TARGET_THUMB1
51+
&& arm_disable_literal_pool
52+
&& GET_CODE (operands[1]) == SYMBOL_REF"
53+
"*
54+
output_asm_insn (\"movs\\t%0, #:upper8_15:%1\", operands);
55+
output_asm_insn (\"lsls\\t%0, #8\", operands);
56+
output_asm_insn (\"adds\\t%0, #:upper0_7:%1\", operands);
57+
output_asm_insn (\"lsls\\t%0, #8\", operands);
58+
output_asm_insn (\"adds\\t%0, #:lower8_15:%1\", operands);
59+
output_asm_insn (\"lsls\\t%0, #8\", operands);
60+
output_asm_insn (\"adds\\t%0, #:lower0_7:%1\", operands);
61+
return \"\";
62+
"
63+
[(set_attr "length" "14")
64+
(set_attr "conds" "clob")]
65+
)
66+
67+
(define_split
68+
[(set (match_operand:SI 0 "register_operand" "")
69+
(match_operand:SI 1 "immediate_operand" ""))]
70+
"TARGET_THUMB1
71+
&& arm_disable_literal_pool
72+
&& GET_CODE (operands[1]) == CONST_INT
73+
&& !satisfies_constraint_I (operands[1])"
74+
[(clobber (const_int 0))]
75+
"
76+
thumb1_gen_const_int (operands[0], INTVAL (operands[1]));
77+
DONE;
78+
"
79+
)
80+
4681
(define_insn "*thumb1_adddi3"
4782
[(set (match_operand:DI 0 "register_operand" "=l")
4883
(plus:DI (match_operand:DI 1 "register_operand" "%0")
@@ -829,8 +864,8 @@
829864
(set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
830865

831866
(define_insn "*thumb1_movhf"
832-
[(set (match_operand:HF 0 "nonimmediate_operand" "=l,l,m,*r,*h")
833-
(match_operand:HF 1 "general_operand" "l,mF,l,*h,*r"))]
867+
[(set (match_operand:HF 0 "nonimmediate_operand" "=l,l,l,m,*r,*h")
868+
(match_operand:HF 1 "general_operand" "l, m,F,l,*h,*r"))]
834869
"TARGET_THUMB1
835870
&& ( s_register_operand (operands[0], HFmode)
836871
|| s_register_operand (operands[1], HFmode))"
@@ -855,14 +890,34 @@
855890
}
856891
return \"ldrh\\t%0, %1\";
857892
}
858-
case 2: return \"strh\\t%1, %0\";
893+
case 2:
894+
{
895+
int bits;
896+
int high;
897+
rtx ops[3];
898+
899+
bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
900+
HFmode);
901+
ops[0] = operands[0];
902+
high = (bits >> 8) & 0xff;
903+
ops[1] = GEN_INT (high);
904+
ops[2] = GEN_INT (bits & 0xff);
905+
if (high != 0)
906+
output_asm_insn (\"movs\\t%0, %1\;lsls\\t%0, #8\;adds\\t%0, %2\", ops);
907+
else
908+
output_asm_insn (\"movs\\t%0, %2\", ops);
909+
910+
return \"\";
911+
}
912+
case 3: return \"strh\\t%1, %0\";
859913
default: return \"mov\\t%0, %1\";
860914
}
861915
"
862-
[(set_attr "length" "2")
863-
(set_attr "type" "mov_reg,load_4,store_4,mov_reg,mov_reg")
864-
(set_attr "pool_range" "*,1018,*,*,*")
865-
(set_attr "conds" "clob,nocond,nocond,nocond,nocond")])
916+
[(set_attr "length" "2,2,6,2,2,2")
917+
(set_attr "type" "mov_reg,load_4,mov_reg,store_4,mov_reg,mov_reg")
918+
(set_attr "pool_range" "*,1018,*,*,*,*")
919+
(set_attr "conds" "clob,nocond,nocond,nocond,nocond,nocond")])
920+
866921
;;; ??? This should have alternatives for constants.
867922
(define_insn "*thumb1_movsf_insn"
868923
[(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")

gcc/doc/invoke.texi

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18227,8 +18227,7 @@ provided for use in debugging the compiler.
1822718227
Do not allow constant data to be placed in code sections.
1822818228
Additionally, when compiling for ELF object format give all text sections the
1822918229
ELF processor-specific section attribute @code{SHF_ARM_PURECODE}. This option
18230-
is only available when generating non-pic code for M-profile targets with the
18231-
MOVT instruction.
18230+
is only available when generating non-pic code for M-profile targets.
1823218231

1823318232
@item -mcmse
1823418233
@opindex mcmse

gcc/testsuite/ChangeLog

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
2019-12-17 Christophe Lyon <[email protected]>
2+
3+
* gcc.target/arm/pr45701-1.c: Adjust for -mpure-code.
4+
* gcc.target/arm/pr45701-2.c: Likewise.
5+
* gcc.target/arm/pure-code/no-literal-pool.c: Add tests for
6+
__fp16.
7+
* gcc.target/arm/pure-code/pure-code.exp: Remove thumb2 and movt
8+
conditions.
9+
* gcc.target/arm/thumb1-Os-mult.c: Skip if -mpure-code is used.
10+
111
2019-12-17 Andrew Stubbs <[email protected]>
212

313
* lib/target-supports.exp

gcc/testsuite/gcc.target/arm/pr45701-1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/* { dg-skip-if "" { ! { arm_thumb1_ok || arm_thumb2_ok } } } */
33
/* { dg-options "-mthumb -Os" } */
44
/* { dg-final { scan-assembler "push\t\{r3" { target { ! arm*-*-uclinuxfdpiceabi } } } } */
5-
/* { dg-final { scan-assembler-not "\[^\-\]r8" { target { ! arm*-*-uclinuxfdpiceabi } } } } */
5+
/* { dg-final { scan-assembler-not "\[^\-e\]r8" { target { ! arm*-*-uclinuxfdpiceabi } } } } */
66

77
extern int hist_verify;
88
extern int a1;

gcc/testsuite/gcc.target/arm/pr45701-2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/* { dg-skip-if "" { ! { arm_thumb1_ok || arm_thumb2_ok } } } */
33
/* { dg-options "-mthumb -Os" } */
44
/* { dg-final { scan-assembler "push\t\{r3" { target { ! arm*-*-uclinuxfdpiceabi } } } } */
5-
/* { dg-final { scan-assembler-not "\[^\-\]r8" { target { ! arm*-*-uclinuxfdpiceabi } } } } */
5+
/* { dg-final { scan-assembler-not "\[^\-e\]r8" { target { ! arm*-*-uclinuxfdpiceabi } } } } */
66

77
extern int hist_verify;
88
extern int a1;

gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
/* { dg-do compile } */
2-
/* { dg-options "-mpure-code" } */
2+
/* { dg-options "-mpure-code -mfp16-format=ieee" } */
33
/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
44

5+
__fp16 hf;
56
float sf;
67
double df;
78
long long l;
89
static char *p = "Hello World";
910

11+
__fp16
12+
testsfp16 (__fp16 *p)
13+
{
14+
hf = 1.3;
15+
*p += hf;
16+
if (*p > 1.1234f)
17+
return 2.1234f;
18+
else
19+
return 3.1234f;
20+
}
21+
1022
float
1123
testsf (float *p)
1224
{

0 commit comments

Comments
 (0)