Commit 2cf63121 by Maciej W. Rozycki Committed by Maciej W. Rozycki

MIPS/GCC: Mark trailing labels with `.insn'

	gcc/
	* config/mips/mips.c (mips16_emit_constants): Emit `consttable'
	insn at the beginning of the constant pool.
	(mips_insert_insn_pseudos): New function.
	(mips_machine_reorg2): Call it.
	* config/mips/mips.md (unspec): Add UNSPEC_CONSTTABLE and
	UNSPEC_INSN_PSEUDO enum values.
	(insn_pseudo, consttable): New insns.

	gcc/testsuite/
	* gcc.target/mips/insn-casesi.c: New test case.
	* gcc.target/mips/insn-pseudo-1.c: New test case.
	* gcc.target/mips/insn-pseudo-2.c: New test case.
	* gcc.target/mips/insn-pseudo-3.c: New test case.
	* gcc.target/mips/insn-pseudo-4.c: New test case.
	* gcc.target/mips/insn-tablejump.c: New test case.

From-SVN: r242424
parent 2cbfb209
2016-11-15 Maciej W. Rozycki <macro@imgtec.com>
* config/mips/mips.c (mips16_emit_constants): Emit `consttable'
insn at the beginning of the constant pool.
(mips_insert_insn_pseudos): New function.
(mips_machine_reorg2): Call it.
* config/mips/mips.md (unspec): Add UNSPEC_CONSTTABLE and
UNSPEC_INSN_PSEUDO enum values.
(insn_pseudo, consttable): New insns.
2016-11-15 Michael Matz <matz@suse.de> 2016-11-15 Michael Matz <matz@suse.de>
PR missed-optimization/77881 PR missed-optimization/77881
...@@ -17140,6 +17140,8 @@ mips16_emit_constants (struct mips16_constant *constants, rtx_insn *insn) ...@@ -17140,6 +17140,8 @@ mips16_emit_constants (struct mips16_constant *constants, rtx_insn *insn)
int align; int align;
align = 0; align = 0;
if (constants)
insn = emit_insn_after (gen_consttable (), insn);
for (c = constants; c != NULL; c = next) for (c = constants; c != NULL; c = next)
{ {
/* If necessary, increase the alignment of PC. */ /* If necessary, increase the alignment of PC. */
...@@ -19015,6 +19017,46 @@ mips16_split_long_branches (void) ...@@ -19015,6 +19017,46 @@ mips16_split_long_branches (void)
while (something_changed); while (something_changed);
} }
/* Insert a `.insn' assembly pseudo-op after any labels followed by
a MIPS16 constant pool or no insn at all. This is needed so that
targets that have been optimized away are still marked as code
and therefore branches that remained and point to them are known
to retain the ISA mode and as such can be successfully assembled. */
static void
mips_insert_insn_pseudos (void)
{
bool insn_pseudo_needed = TRUE;
rtx_insn *insn;
for (insn = get_last_insn (); insn != NULL_RTX; insn = PREV_INSN (insn))
switch (GET_CODE (insn))
{
case INSN:
if (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
&& XINT (PATTERN (insn), 1) == UNSPEC_CONSTTABLE)
{
insn_pseudo_needed = TRUE;
break;
}
/* Fall through. */
case JUMP_INSN:
case CALL_INSN:
case JUMP_TABLE_DATA:
insn_pseudo_needed = FALSE;
break;
case CODE_LABEL:
if (insn_pseudo_needed)
{
emit_insn_after (gen_insn_pseudo (), insn);
insn_pseudo_needed = FALSE;
}
break;
default:
break;
}
}
/* Implement TARGET_MACHINE_DEPENDENT_REORG. */ /* Implement TARGET_MACHINE_DEPENDENT_REORG. */
static void static void
...@@ -19050,6 +19092,7 @@ mips_machine_reorg2 (void) ...@@ -19050,6 +19092,7 @@ mips_machine_reorg2 (void)
optimizations, but this should be an extremely rare case anyhow. */ optimizations, but this should be an extremely rare case anyhow. */
mips_reorg_process_insns (); mips_reorg_process_insns ();
mips16_split_long_branches (); mips16_split_long_branches ();
mips_insert_insn_pseudos ();
return 0; return 0;
} }
......
...@@ -120,6 +120,7 @@ ...@@ -120,6 +120,7 @@
;; MIPS16 constant pools. ;; MIPS16 constant pools.
UNSPEC_ALIGN UNSPEC_ALIGN
UNSPEC_CONSTTABLE
UNSPEC_CONSTTABLE_INT UNSPEC_CONSTTABLE_INT
UNSPEC_CONSTTABLE_FLOAT UNSPEC_CONSTTABLE_FLOAT
...@@ -151,6 +152,9 @@ ...@@ -151,6 +152,9 @@
;; Stack checking. ;; Stack checking.
UNSPEC_PROBE_STACK_RANGE UNSPEC_PROBE_STACK_RANGE
;; The `.insn' pseudo-op.
UNSPEC_INSN_PSEUDO
]) ])
(define_constants (define_constants
...@@ -7174,6 +7178,14 @@ ...@@ -7174,6 +7178,14 @@
return "#nop"; return "#nop";
} }
[(set_attr "type" "nop")]) [(set_attr "type" "nop")])
;; The `.insn' pseudo-op.
(define_insn "insn_pseudo"
[(unspec_volatile [(const_int 0)] UNSPEC_INSN_PSEUDO)]
""
".insn"
[(set_attr "mode" "none")
(set_attr "insn_count" "0")])
;; MIPS4 Conditional move instructions. ;; MIPS4 Conditional move instructions.
...@@ -7308,6 +7320,13 @@ ...@@ -7308,6 +7320,13 @@
;; .................... ;; ....................
;; ;;
(define_insn "consttable"
[(unspec_volatile [(const_int 0)] UNSPEC_CONSTTABLE)]
""
""
[(set_attr "mode" "none")
(set_attr "insn_count" "0")])
(define_insn "consttable_tls_reloc" (define_insn "consttable_tls_reloc"
[(unspec_volatile [(match_operand 0 "tls_reloc_operand" "") [(unspec_volatile [(match_operand 0 "tls_reloc_operand" "")
(match_operand 1 "const_int_operand" "")] (match_operand 1 "const_int_operand" "")]
......
2016-11-15 Maciej W. Rozycki <macro@imgtec.com> 2016-11-15 Maciej W. Rozycki <macro@imgtec.com>
* gcc.target/mips/insn-casesi.c: New test case.
* gcc.target/mips/insn-pseudo-1.c: New test case.
* gcc.target/mips/insn-pseudo-2.c: New test case.
* gcc.target/mips/insn-pseudo-3.c: New test case.
* gcc.target/mips/insn-pseudo-4.c: New test case.
* gcc.target/mips/insn-tablejump.c: New test case.
2016-11-15 Maciej W. Rozycki <macro@imgtec.com>
* gcc.target/mips/mips.exp (mips_option_tests): Add * gcc.target/mips/mips.exp (mips_option_tests): Add
`-mcode-readable=yes' array element. `-mcode-readable=yes' array element.
......
/* { dg-do run } */
/* { dg-options "-mips16 -mcode-readable=yes" } */
int __attribute__ ((noinline))
frob (int i)
{
switch (i)
{
case -5:
return -2;
case -3:
return -1;
case 0:
return 0;
case 3:
return 1;
case 5:
break;
default:
__builtin_unreachable ();
}
return i;
}
int
main (int argc, char **argv)
{
asm ("" : "+r" (argc));
argc = frob ((argc & 10) - 5);
asm ("" : "+r" (argc));
return !argc;
}
/* This will result in assembly like:
.text
.align 2
.globl frob
.set mips16
.set nomicromips
.ent frob
.type frob, @function
frob:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
addiu $2,$4,5
sltu $2,11
bteqz $L2
sll $3,$2,1
la $2,$L4
addu $3,$2,$3
lh $3,0($3)
addu $2,$2,$3
j $2
.align 1
.align 2
$L4:
.half $L3-$L4
.half $L2-$L4
.half $L9-$L4
.half $L2-$L4
.half $L2-$L4
.half $L8-$L4
.half $L2-$L4
.half $L2-$L4
.half $L7-$L4
.half $L2-$L4
.half $L8-$L4
$L8:
.set noreorder
.set nomacro
jr $31
move $2,$4
.set macro
.set reorder
$L9:
li $2,1
.set noreorder
.set nomacro
jr $31
neg $2,$2
.set macro
.set reorder
$L3:
li $2,2
.set noreorder
.set nomacro
jr $31
neg $2,$2
.set macro
.set reorder
$L7:
.set noreorder
.set nomacro
jr $31
li $2,1
.set macro
.set reorder
$L2:
.insn
.end frob
.size frob, .-frob
for `frob' and we want to make sure it links correctly owing to the
`.insn' pseudo-op which needs to be there at `$L2' as there's no
code following and the label is a MIPS16 branch target (even though
the branch is never taken. See also insn-tablejump.c. */
/* { dg-do compile } */
/* { dg-options "-mno-micromips -mno-mips16" } */
void
unreachable (int i)
{
asm volatile goto ("b\t.\n\tbeqz\t%0,%l1" : : "r" (i) : : punt);
punt:
__builtin_unreachable ();
}
/* Expect assembly like:
beqz $4,$L2
# Anything goes here.
$L2: # The label must match.
.insn
$L3 = . # It's there, but we don't care.
.end unreachable
that is .insn to be inserted if a code label is at function's end. */
/* { dg-final { scan-assembler "\tbeqz\t\\\$\[0-9\]+,(.L\[0-9\]+)\n.*\n\\1:\n\t\\.insn\n(?:.L\[0-9\]+ = \\.\n)?\t\\.end\tunreachable\n" } } */
/* { dg-do compile } */
/* { dg-options "-mmicromips" } */
void
unreachable (int i)
{
asm volatile goto ("b\t.\n\tbeqz\t%0,%l1" : : "r" (i) : : punt);
punt:
__builtin_unreachable ();
}
/* Expect assembly like:
beqz $4,$L2
# Anything goes here.
$L2: # The label must match.
.insn
$L3 = . # It's there, but we don't care.
.end unreachable
that is .insn to be inserted if a code label is at function's end. */
/* { dg-final { scan-assembler "\tbeqz\t\\\$\[0-9\]+,(.L\[0-9\]+)\n.*\n\\1:\n\t\\.insn\n(?:.L\[0-9\]+ = \\.\n)?\t\\.end\tunreachable\n" } } */
/* { dg-do compile } */
/* { dg-options "-mips16" } */
void
unreachable (int i)
{
asm volatile goto ("b\t.\n\tbeqz\t%0,%l1" : : "r" (i) : : punt);
punt:
__builtin_unreachable ();
}
/* Expect assembly like:
beqz $4,$L2
# Anything goes here.
$L2: # The label must match.
.insn
$L3 = . # It's there, but we don't care.
.end unreachable
that is .insn to be inserted if a code label is at function's end. */
/* { dg-final { scan-assembler "\tbeqz\t\\\$\[0-9\]+,(.L\[0-9\]+)\n.*\n\\1:\n\t\\.insn\n(?:.L\[0-9\]+ = \\.\n)?\t\\.end\tunreachable\n" } } */
/* { dg-do compile } */
/* { dg-options "-mips16 -mcode-readable=yes" } */
void
unreachable (void)
{
asm volatile goto ("b\t.\n\tbeqz\t%0,%l1" : : "r" (0x12345678) : : punt);
punt:
__builtin_unreachable ();
}
/* Expect assembly like:
lw $2,$L5
# Anything goes here.
beqz $2,$L2 # The register must match.
# Anything goes here.
$L2: # The label must match.
.insn
$L3 = . # It's there, but we don't care.
.align 2
$L5: # The label must match.
.word 305419896
that is .insn to be inserted if a code label is at a constant pool. */
/* { dg-final { scan-assembler "\tlw\t(\\\$\[0-9\]+),(.L\[0-9\]+)\n.*\tbeqz\t\\1,(.L\[0-9\]+)\n.*\n\\3:\n\t\\.insn\n(?:.L\[0-9\]+ = \\.\n)?\t\\.align\t2\n\\2:\n\t\\.word\t305419896\n" } } */
/* { dg-do run } */
/* { dg-options "-mmicromips" } */
int __attribute__ ((noinline))
frob (int i)
{
switch (i)
{
case -5:
return -2;
case -3:
return -1;
case 0:
return 0;
case 3:
return 1;
case 5:
break;
default:
__builtin_unreachable ();
}
return i;
}
int
main (int argc, char **argv)
{
asm ("" : "+r" (argc));
argc = frob ((argc & 10) - 5);
asm ("" : "+r" (argc));
return !argc;
}
/* This will result in assembly like:
.text
.align 2
.globl frob
.set nomips16
.set micromips
.ent frob
.type frob, @function
frob:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
.set noreorder
.set nomacro
addiu $3,$4,5
sltu $2,$3,11
beqzc $2,$L2
lui $2,%hi($L4)
addiu $2,$2,%lo($L4)
lwxs $3,$3($2)
jrc $3
.rdata
.align 2
.align 2
$L4:
.word $L3
.word $L2
.word $L9
.word $L2
.word $L2
.word $L8
.word $L2
.word $L2
.word $L7
.word $L2
.word $L8
.text
$L8:
jr $31
move $2,$4
$L9:
jr $31
li $2,-1 # 0xffffffffffffffff
$L3:
jr $31
li $2,-2 # 0xfffffffffffffffe
$L7:
jr $31
li $2,1 # 0x1
$L2:
.insn
.set macro
.set reorder
.end frob
.size frob, .-frob
for `frob' and we want to make sure it links correctly owing to the
`.insn' pseudo-op which needs to be there at `$L2' as there's no
code following and the label is a microMIPS branch target (even though
the branch is never taken. See also insn-casesi.c. */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment