Commit 7c59dc5d by Michael Meissner

try to fix NT trampolines

From-SVN: r11360
parent 375490e0
...@@ -4035,6 +4035,7 @@ rs6000_trampoline_template (file) ...@@ -4035,6 +4035,7 @@ rs6000_trampoline_template (file)
{ {
char *sc = reg_names[STATIC_CHAIN_REGNUM]; char *sc = reg_names[STATIC_CHAIN_REGNUM];
char *r0 = reg_names[0]; char *r0 = reg_names[0];
char *r2 = reg_names[2];
switch (DEFAULT_ABI) switch (DEFAULT_ABI)
{ {
...@@ -4087,23 +4088,26 @@ rs6000_trampoline_template (file) ...@@ -4087,23 +4088,26 @@ rs6000_trampoline_template (file)
/* NT function pointers point to a two word area (real address, TOC) /* NT function pointers point to a two word area (real address, TOC)
which unfortunately does not include a static chain field. So we which unfortunately does not include a static chain field. So we
need to have a 2 word area followed by the code to load up the use the function field to point to ..LTRAMP1 and the toc field
static chain. */ to point to the whole table. */
case ABI_NT: case ABI_NT:
if (STATIC_CHAIN_REGNUM == 0 || !TARGET_NEW_MNEMONICS || TARGET_64BIT) if (STATIC_CHAIN_REGNUM == 0
|| STATIC_CHAIN_REGNUM == 2
|| TARGET_64BIT
|| !TARGET_NEW_MNEMONICS)
abort (); abort ();
fprintf (file, "\t.ualong 0,0\n"); /* offset 0 */ fprintf (file, "\t.ualong 0\n"); /* offset 0 */
fprintf (file, "\tmflr %s\n", r0); /* offset 8 */ fprintf (file, "\t.ualong 0\n"); /* offset 4 */
fprintf (file, "\tbl .LTRAMP1\n"); /* offset 12 */ fprintf (file, "\t.ualong 0\n"); /* offset 8 */
fprintf (file, "\t.ualong 0,0\n"); /* offset 16 */ fprintf (file, "\t.ualong 0\n"); /* offset 12 */
fprintf (file, ".LTRAMP1:\n"); fprintf (file, "\t.ualong 0\n"); /* offset 16 */
fprintf (file, "\tmflr %s\n", sc); /* offset 28 */ fprintf (file, "..LTRAMP1:\n"); /* offset 20 */
fprintf (file, "\tmtlr %s\n", r0); /* offset 32 */ fprintf (file, "\tlwz %s,8(%s)\n", r0, r2); /* offset 24 */
fprintf (file, "\tlwz %s,0(%s)\n", r0, sc); /* offset 36 */ fprintf (file, "\tlwz %s,12(%s)\n", sc, r2); /* offset 28 */
fprintf (file, "\tlwz %s,4(%s)\n", sc, sc); /* offset 40 */ fprintf (file, "\tmtctr %s\n", r0); /* offset 32 */
fprintf (file, "\tmtctr %s\n", r0); /* offset 44 */ fprintf (file, "\tlwz %s,16(%s)\n", r2, r2); /* offset 36 */
fprintf (file, "\tbctr\n"); /* offset 48 */ fprintf (file, "\tbctr\n"); /* offset 40 */
break; break;
} }
...@@ -4132,7 +4136,7 @@ rs6000_trampoline_size () ...@@ -4132,7 +4136,7 @@ rs6000_trampoline_size ()
break; break;
case ABI_NT: case ABI_NT:
ret = 52; ret = 20;
break; break;
} }
...@@ -4157,22 +4161,15 @@ rs6000_initialize_trampoline (addr, fnaddr, cxt) ...@@ -4157,22 +4161,15 @@ rs6000_initialize_trampoline (addr, fnaddr, cxt)
default: default:
abort (); abort ();
#define MEM_PLUS(addr,offset) gen_rtx (MEM, pmode, memory_address (pmode, plus_constant (addr, offset)))
/* Under AIX, just build the 3 word function descriptor */ /* Under AIX, just build the 3 word function descriptor */
case ABI_AIX: case ABI_AIX:
emit_move_insn (gen_rtx (MEM, pmode, emit_move_insn (gen_rtx (MEM, pmode, memory_address (pmode, addr)),
memory_address (pmode, (addr))), gen_rtx (MEM, pmode, memory_address (pmode, fnaddr)));
gen_rtx (MEM, pmode,
memory_address (pmode, (fnaddr)))); emit_move_insn (MEM_PLUS (addr, 4), MEM_PLUS (fnaddr, 4));
emit_move_insn (gen_rtx (MEM, pmode, emit_move_insn (MEM_PLUS (addr, 8), force_reg (pmode, cxt));
memory_address (pmode,
plus_constant ((addr), 4))),
gen_rtx (MEM, pmode,
memory_address (pmode,
plus_constant ((fnaddr), 4))));
emit_move_insn (gen_rtx (MEM, pmode,
memory_address (pmode,
plus_constant ((addr), 8))),
force_reg (pmode, (cxt)));
break; break;
/* Under V.4/eabi, update the two words after the bl to have the real /* Under V.4/eabi, update the two words after the bl to have the real
...@@ -4182,31 +4179,27 @@ rs6000_initialize_trampoline (addr, fnaddr, cxt) ...@@ -4182,31 +4179,27 @@ rs6000_initialize_trampoline (addr, fnaddr, cxt)
reg = gen_reg_rtx (pmode); reg = gen_reg_rtx (pmode);
emit_move_insn (reg, fnaddr); emit_move_insn (reg, fnaddr);
emit_move_insn (gen_rtx (MEM, pmode, plus_constant (addr, 8)), reg); emit_move_insn (MEM_PLUS (addr, 8), reg);
emit_move_insn (gen_rtx (MEM, pmode, emit_move_insn (MEM_PLUS (addr, (TARGET_64BIT ? 16 : 12)), cxt);
plus_constant (addr, (TARGET_64BIT ? 16 : 12))),
cxt);
rs6000_sync_trampoline (addr); rs6000_sync_trampoline (addr);
break; break;
/* Under NT, update the first 2 words to look like a normal descriptor, and /* Under NT, update the first word to point to the ..LTRAMP1 header,
then fill in the fields with the function address and static chain after second word will point to the whole trampoline, third-fifth words
the bl instruction. */ will then have the real address, static chain, and toc value. */
case ABI_NT: case ABI_NT:
reg = gen_reg_rtx (pmode); addr = force_reg (pmode, addr);
reg = gen_reg_rtx (pmode);
reg2 = gen_reg_rtx (pmode); reg2 = gen_reg_rtx (pmode);
reg3 = gen_reg_rtx (pmode); emit_move_insn (reg, gen_rtx (SYMBOL_REF, pmode, "..LTRAMP1"));
emit_move_insn (reg2, fnaddr);
emit_move_insn (gen_rtx (MEM, pmode, plus_constant (addr, 4)), reg3 = force_reg (pmode, cxt);
gen_rtx (REG, pmode, 2)); emit_move_insn (MEM_PLUS (addr, 4), addr);
emit_move_insn (reg, fnaddr); emit_move_insn (gen_rtx (MEM, pmode, addr), reg);
emit_move_insn (reg2, gen_rtx (MEM, pmode, reg)); emit_move_insn (MEM_PLUS (addr, 8), reg2);
emit_move_insn (reg3, plus_constant (addr, 8)); emit_move_insn (MEM_PLUS (addr, 12), reg3);
emit_move_insn (gen_rtx (MEM, pmode, plus_constant (addr, 16)), reg); emit_move_insn (MEM_PLUS (addr, 16), gen_rtx (REG, pmode, 2));
emit_move_insn (gen_rtx (MEM, pmode, addr), reg3);
emit_move_insn (gen_rtx (MEM, pmode, plus_constant (addr, 20)), cxt);
rs6000_sync_trampoline (addr);
break; break;
} }
......
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