Skip to content

Commit 9c5db94

Browse files
author
Christophe Lyon
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, riscvarchive#8 adds r3, #:upper0_7:#.LC2 lsls r3, riscvarchive#8 adds r3, #:lower8_15:#.LC2 lsls r3, riscvarchive#8 adds r3, #:lower0_7:#.LC2 ldr r3, [r3] ldr r3, [r3] adds r3, r3, riscvarchive#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, riscvarchive#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. 2020-02-25 Christophe Lyon <[email protected]> Backport from mainline 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.
1 parent eeb3139 commit 9c5db94

File tree

12 files changed

+198
-30
lines changed

12 files changed

+198
-30
lines changed

gcc/ChangeLog

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

321
PR rtl-optimization/93908

gcc/config/arm/arm-protos.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ extern bool arm_small_register_classes_for_mode_p (machine_mode);
6666
extern int const_ok_for_arm (HOST_WIDE_INT);
6767
extern int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
6868
extern int const_ok_for_dimode_op (HOST_WIDE_INT, enum rtx_code);
69+
extern void thumb1_gen_const_int (rtx, HOST_WIDE_INT);
6970
extern int arm_split_constant (RTX_CODE, machine_mode, rtx,
7071
HOST_WIDE_INT, rtx, rtx, int);
7172
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
@@ -2904,13 +2904,18 @@ arm_option_check_internal (struct gcc_options *opts)
29042904
{
29052905
const char *flag = (target_pure_code ? "-mpure-code" :
29062906
"-mslow-flash-data");
2907+
bool common_unsupported_modes = arm_arch_notm || flag_pic || TARGET_NEON;
29072908

2908-
/* We only support -mpure-code and -mslow-flash-data on M-profile targets
2909-
with MOVT. */
2910-
if (!TARGET_HAVE_MOVT || arm_arch_notm || flag_pic || TARGET_NEON)
2909+
/* We only support -mslow-flash-data on M-profile targets with
2910+
MOVT. */
2911+
if (target_slow_flash_data && (!TARGET_HAVE_MOVT || common_unsupported_modes))
29112912
error ("%s only supports non-pic code on M-profile targets with the "
29122913
"MOVT instruction", flag);
29132914

2915+
/* We only support -mpure-code on M-profile targets. */
2916+
if (target_pure_code && common_unsupported_modes)
2917+
error ("%s only supports non-pic code on M-profile targets", flag);
2918+
29142919
/* Cannot load addresses: -mslow-flash-data forbids literal pool and
29152920
-mword-relocations forbids relocation of MOVT/MOVW. */
29162921
if (target_word_relocations)
@@ -4316,6 +4321,38 @@ const_ok_for_dimode_op (HOST_WIDE_INT i, enum rtx_code code)
43164321
}
43174322
}
43184323

4324+
/* Emit a sequence of movs/adds/shift to produce a 32-bit constant.
4325+
Avoid generating useless code when one of the bytes is zero. */
4326+
void
4327+
thumb1_gen_const_int (rtx op0, HOST_WIDE_INT op1)
4328+
{
4329+
bool mov_done_p = false;
4330+
int i;
4331+
4332+
/* Emit upper 3 bytes if needed. */
4333+
for (i = 0; i < 3; i++)
4334+
{
4335+
int byte = (op1 >> (8 * (3 - i))) & 0xff;
4336+
4337+
if (byte)
4338+
{
4339+
emit_set_insn (op0, mov_done_p
4340+
? gen_rtx_PLUS (SImode,op0, GEN_INT (byte))
4341+
: GEN_INT (byte));
4342+
mov_done_p = true;
4343+
}
4344+
4345+
if (mov_done_p)
4346+
emit_set_insn (op0, gen_rtx_ASHIFT (SImode, op0, GEN_INT (8)));
4347+
}
4348+
4349+
/* Emit lower byte if needed. */
4350+
if (!mov_done_p)
4351+
emit_set_insn (op0, GEN_INT (op1 & 0xff));
4352+
else if (op1 & 0xff)
4353+
emit_set_insn (op0, gen_rtx_PLUS (SImode, op0, GEN_INT (op1 & 0xff)));
4354+
}
4355+
43194356
/* Emit a sequence of insns to handle a large constant.
43204357
CODE is the code of the operation required, it can be any of SET, PLUS,
43214358
IOR, AND, XOR, MINUS;
@@ -8325,7 +8362,8 @@ thumb1_legitimate_address_p (machine_mode mode, rtx x, int strict_p)
83258362
/* This is PC relative data before arm_reorg runs. */
83268363
else if (GET_MODE_SIZE (mode) >= 4 && CONSTANT_P (x)
83278364
&& GET_CODE (x) == SYMBOL_REF
8328-
&& CONSTANT_POOL_ADDRESS_P (x) && !flag_pic)
8365+
&& CONSTANT_POOL_ADDRESS_P (x) && !flag_pic
8366+
&& !arm_disable_literal_pool)
83298367
return 1;
83308368

83318369
/* This is PC relative data after arm_reorg runs. */
@@ -8393,6 +8431,7 @@ thumb1_legitimate_address_p (machine_mode mode, rtx x, int strict_p)
83938431
&& GET_MODE_SIZE (mode) == 4
83948432
&& GET_CODE (x) == SYMBOL_REF
83958433
&& CONSTANT_POOL_ADDRESS_P (x)
8434+
&& !arm_disable_literal_pool
83968435
&& ! (flag_pic
83978436
&& symbol_mentioned_p (get_pool_constant (x))
83988437
&& ! pcrel_constant_p (get_pool_constant (x))))
@@ -9028,7 +9067,9 @@ thumb1_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
90289067
return 0;
90299068
if (thumb_shiftable_const (INTVAL (x)))
90309069
return COSTS_N_INSNS (2);
9031-
return COSTS_N_INSNS (3);
9070+
return arm_disable_literal_pool
9071+
? COSTS_N_INSNS (8)
9072+
: COSTS_N_INSNS (3);
90329073
}
90339074
else if ((outer == PLUS || outer == COMPARE)
90349075
&& INTVAL (x) < 256 && INTVAL (x) > -256)
@@ -9185,7 +9226,9 @@ thumb1_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
91859226
/* See split "TARGET_THUMB1 && satisfies_constraint_K". */
91869227
if (thumb_shiftable_const (INTVAL (x)))
91879228
return COSTS_N_INSNS (2);
9188-
return COSTS_N_INSNS (3);
9229+
return arm_disable_literal_pool
9230+
? COSTS_N_INSNS (8)
9231+
: COSTS_N_INSNS (3);
91899232
}
91909233
else if ((outer == PLUS || outer == COMPARE)
91919234
&& INTVAL (x) < 256 && INTVAL (x) > -256)
@@ -26832,14 +26875,41 @@ arm_thumb1_mi_thunk (FILE *file, tree, HOST_WIDE_INT delta,
2683226875
/* push r3 so we can use it as a temporary. */
2683326876
/* TODO: Omit this save if r3 is not used. */
2683426877
fputs ("\tpush {r3}\n", file);
26835-
fputs ("\tldr\tr3, ", file);
26878+
26879+
/* With -mpure-code, we cannot load the address from the
26880+
constant pool: we build it explicitly. */
26881+
if (target_pure_code)
26882+
{
26883+
fputs ("\tmovs\tr3, #:upper8_15:#", file);
26884+
assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
26885+
fputc ('\n', file);
26886+
fputs ("\tlsls r3, #8\n", file);
26887+
fputs ("\tadds\tr3, #:upper0_7:#", file);
26888+
assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
26889+
fputc ('\n', file);
26890+
fputs ("\tlsls r3, #8\n", file);
26891+
fputs ("\tadds\tr3, #:lower8_15:#", file);
26892+
assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
26893+
fputc ('\n', file);
26894+
fputs ("\tlsls r3, #8\n", file);
26895+
fputs ("\tadds\tr3, #:lower0_7:#", file);
26896+
assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
26897+
fputc ('\n', file);
26898+
}
26899+
else
26900+
fputs ("\tldr\tr3, ", file);
2683626901
}
2683726902
else
2683826903
{
2683926904
fputs ("\tldr\tr12, ", file);
2684026905
}
26841-
assemble_name (file, label);
26842-
fputc ('\n', file);
26906+
26907+
if (!target_pure_code)
26908+
{
26909+
assemble_name (file, label);
26910+
fputc ('\n', file);
26911+
}
26912+
2684326913
if (flag_pic)
2684426914
{
2684526915
/* 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
@@ -1854,9 +1854,11 @@ enum arm_auto_incmodes
18541854
for the index in the tablejump instruction. */
18551855
#define CASE_VECTOR_MODE Pmode
18561856

1857-
#define CASE_VECTOR_PC_RELATIVE (TARGET_THUMB2 \
1858-
|| (TARGET_THUMB1 \
1859-
&& (optimize_size || flag_pic)))
1857+
#define CASE_VECTOR_PC_RELATIVE ((TARGET_THUMB2 \
1858+
|| (TARGET_THUMB1 \
1859+
&& (optimize_size || flag_pic))) \
1860+
&& (!target_pure_code))
1861+
18601862

18611863
#define CASE_VECTOR_SHORTEN_MODE(min, max, body) \
18621864
(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
@@ -17920,8 +17920,7 @@ provided for use in debugging the compiler.
1792017920
Do not allow constant data to be placed in code sections.
1792117921
Additionally, when compiling for ELF object format give all text sections the
1792217922
ELF processor-specific section attribute @code{SHF_ARM_PURECODE}. This option
17923-
is only available when generating non-pic code for M-profile targets with the
17924-
MOVT instruction.
17923+
is only available when generating non-pic code for M-profile targets.
1792517924

1792617925
@item -mcmse
1792717926
@opindex mcmse

gcc/testsuite/ChangeLog

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

316
PR rtl-optimization/93908

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" } } */
5-
/* { dg-final { scan-assembler-not "\[^\-\]r8" } } */
5+
/* { dg-final { scan-assembler-not "\[^\-e\]r8" } } */
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" } } */
5-
/* { dg-final { scan-assembler-not "\[^\-\]r8" } } */
5+
/* { dg-final { scan-assembler-not "\[^\-e\]r8" } } */
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
{

gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,8 @@ if ![info exists DEFAULT_CFLAGS] then {
2525
set DEFAULT_CFLAGS " -ansi -pedantic-errors"
2626
}
2727

28-
# The -mpure-code option is only available for M-profile targets that support
29-
# the MOVT instruction.
30-
if {([check_effective_target_arm_thumb2_ok]
31-
|| [check_effective_target_arm_thumb1_movt_ok])
32-
&& [check_effective_target_arm_cortex_m]} then {
28+
# The -mpure-code option is only available for M-profile targets.
29+
if {[check_effective_target_arm_cortex_m]} then {
3330
# Initialize `dg'.
3431
dg-init
3532

@@ -56,4 +53,4 @@ set LTO_TORTURE_OPTIONS ${saved-lto_torture_options}
5653

5754
# All done.
5855
dg-finish
59-
}
56+
#}

gcc/testsuite/gcc.target/arm/thumb1-Os-mult.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* { dg-do compile } */
22
/* { dg-require-effective-target arm_thumb1_ok } */
33
/* { dg-options "-Os" } */
4+
/* { dg-skip-if "-mpure-code generates an inline multiplication code sequence" { *-*-* } { "-mpure-code" } } */
45
/* { dg-skip-if "" { ! { arm_thumb1 } } } */
56

67
int

0 commit comments

Comments
 (0)