diff options
author | Michael Meissner <meissner@gcc.gnu.org> | 1996-02-28 21:09:54 +0000 |
---|---|---|
committer | Michael Meissner <meissner@gcc.gnu.org> | 1996-02-28 21:09:54 +0000 |
commit | 8bd04c565300c201dca9307a5a9173ed31d02494 (patch) | |
tree | 8e8400f60c9287d5802e572a5ec95095b6bab2a9 | |
parent | 7c59dc5dd818d8658902070cab03c57d331b4185 (diff) | |
download | gcc-8bd04c565300c201dca9307a5a9173ed31d02494.zip gcc-8bd04c565300c201dca9307a5a9173ed31d02494.tar.gz gcc-8bd04c565300c201dca9307a5a9173ed31d02494.tar.bz2 |
Update NT code so it works
From-SVN: r11361
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 65 |
1 files changed, 38 insertions, 27 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 20c72d2..54f552a 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -4102,7 +4102,7 @@ rs6000_trampoline_template (file) fprintf (file, "\t.ualong 0\n"); /* offset 8 */ fprintf (file, "\t.ualong 0\n"); /* offset 12 */ fprintf (file, "\t.ualong 0\n"); /* offset 16 */ - fprintf (file, "..LTRAMP1:\n"); /* offset 20 */ + fprintf (file, "..LTRAMP1..0:\n"); /* offset 20 */ fprintf (file, "\tlwz %s,8(%s)\n", r0, r2); /* offset 24 */ fprintf (file, "\tlwz %s,12(%s)\n", sc, r2); /* offset 28 */ fprintf (file, "\tmtctr %s\n", r0); /* offset 32 */ @@ -4153,53 +4153,64 @@ rs6000_initialize_trampoline (addr, fnaddr, cxt) rtx fnaddr; rtx cxt; { - rtx reg, reg2, reg3; enum machine_mode pmode = Pmode; + int regsize = (TARGET_32BIT) ? 4 : 8; + rtx ctx_reg = force_reg (pmode, cxt); switch (DEFAULT_ABI) { default: abort (); +/* Macros to shorten the code expansions below. */ +#define MEM_DEREF(addr) gen_rtx (MEM, pmode, memory_address (pmode, addr)) #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 */ case ABI_AIX: - emit_move_insn (gen_rtx (MEM, pmode, memory_address (pmode, addr)), - gen_rtx (MEM, pmode, memory_address (pmode, fnaddr))); - - emit_move_insn (MEM_PLUS (addr, 4), MEM_PLUS (fnaddr, 4)); - emit_move_insn (MEM_PLUS (addr, 8), force_reg (pmode, cxt)); + { + rtx fn_reg = gen_reg_rtx (pmode); + rtx toc_reg = gen_reg_rtx (pmode); + emit_move_insn (fn_reg, MEM_DEREF (fnaddr)); + emit_move_insn (toc_reg, MEM_PLUS (fnaddr, 4)); + emit_move_insn (MEM_DEREF (addr), fn_reg); + emit_move_insn (MEM_PLUS (addr, regsize), toc_reg); + emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg); + } break; /* Under V.4/eabi, update the two words after the bl to have the real function address and the static chain. */ case ABI_V4: case ABI_AIX_NODESC: - reg = gen_reg_rtx (pmode); - - emit_move_insn (reg, fnaddr); - emit_move_insn (MEM_PLUS (addr, 8), reg); - emit_move_insn (MEM_PLUS (addr, (TARGET_64BIT ? 16 : 12)), cxt); - - rs6000_sync_trampoline (addr); + { + rtx reg = gen_reg_rtx (pmode); + emit_move_insn (reg, fnaddr); + emit_move_insn (MEM_PLUS (addr, 8), reg); + emit_move_insn (MEM_PLUS (addr, 8 + regsize), ctx_reg); + rs6000_sync_trampoline (addr); + } break; - /* Under NT, update the first word to point to the ..LTRAMP1 header, - second word will point to the whole trampoline, third-fifth words + /* Under NT, update the first word to point to the ..LTRAMP1..0 header, + the second word will point to the whole trampoline, third-fifth words will then have the real address, static chain, and toc value. */ case ABI_NT: - addr = force_reg (pmode, addr); - reg = gen_reg_rtx (pmode); - reg2 = gen_reg_rtx (pmode); - emit_move_insn (reg, gen_rtx (SYMBOL_REF, pmode, "..LTRAMP1")); - emit_move_insn (reg2, fnaddr); - reg3 = force_reg (pmode, cxt); - emit_move_insn (MEM_PLUS (addr, 4), addr); - emit_move_insn (gen_rtx (MEM, pmode, addr), reg); - emit_move_insn (MEM_PLUS (addr, 8), reg2); - emit_move_insn (MEM_PLUS (addr, 12), reg3); - emit_move_insn (MEM_PLUS (addr, 16), gen_rtx (REG, pmode, 2)); + { + rtx tramp_reg = gen_reg_rtx (pmode); + rtx fn_reg = gen_reg_rtx (pmode); + rtx toc_reg = gen_reg_rtx (pmode); + + emit_move_insn (tramp_reg, gen_rtx (SYMBOL_REF, pmode, "..LTRAMP1..0")); + addr = force_reg (pmode, addr); + emit_move_insn (fn_reg, MEM_DEREF (fnaddr)); + emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize)); + emit_move_insn (MEM_DEREF (addr), tramp_reg); + emit_move_insn (MEM_PLUS (addr, regsize), addr); + emit_move_insn (MEM_PLUS (addr, 2*regsize), fn_reg); + emit_move_insn (MEM_PLUS (addr, 3*regsize), ctx_reg); + emit_move_insn (MEM_PLUS (addr, 4*regsize), gen_rtx (REG, pmode, 2)); + } break; } |