This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH][m68k] Fix 'value out of range' error for jump table references


Andreas Schwab wrote:
Maxim Kuvyrkov <maxim@codesourcery.com> writes:

Hello, Andreas,

The below patch forbids use of addressing mode 7 (PC-relative indexed with
offset) for jump table references on certain targets.

On ColdFire the offset in mode 7 must fit within 1 byte.  If the jump
table is big enough (i.e., case's in switch statement contain big chunks
of code) the offset might overflow 127 bytes limit which will result in
value out of range' error at assembly-time.

That mode should only be used to address the jump table, which should be located directly after the insn, thus the offset should be guarateed to fit.

After a long delay I've came upon a testcase which exposes the problem.


m68k uses the following sequence to generate a tablejump:

<snip>
move.w <table>(%pc, <index> * 2), <reg>
jmp %pc@(<reg>)

(barrier)

<table>:
  .word <label1> - <table>
    ...
  .word <labelN> - <table>
</snip>

The important thing here is that move.w instruction should be close enough to <table>. After the expand the above holds true, but optimization passes don't see anything special about move.w <label> and, in some cases, can move this instruction so far, that the offset to <table> won't fit into reserved space and the assembler will fail.

I'm not sure what is the best fix in this situation. One option is to forbid such addressing mode as per patch attached in the previous message. Another alternative is to combine both move.w and jmp into one define_insn. Any other suggestions?

The particular testcase I'm looking at is compiled with

m68k-uclinux-gcc -mcpu=5329 gcc.c-torture/compile/pr34688.c -c -O3 -fomit-frame-pointer -mid-shared-library

and the resultant code looks like this:

php_conv_qprint_decode_convert:
<CUT>
	move.w .L7(%pc,%a0.l*2),%d3
.L14:
<CUT>
.L15:
	ext.l %d3
	jmp %pc@(2,%d3:l)
	.balignw 2,0x284c
.L7:
	.word .L3-.L7
	.word .L4-.L7
	.word .L5-.L7
	.word .L6-.L7
	.word .L6-.L7
.L4:
<CUT>
.L5:
<CUT>
.L6:
<CUT>
.L3:
<CUT>
.L17:
<CUT>
	move.w .L7(%pc,%a4.l*2),%d3
	jra .L15
.L18:
<CUT>
	move.w .L7(%pc,%d5.l*2),%d3
	jra .L15
.L10:
<CUT>
	move.w .L7(%pc,%d6.l*2),%d3
	jra .L14


Thanks,


Maxim


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]