diff options
Diffstat (limited to '')
-rw-r--r-- | src/host/buildvm_asm.c | 59 |
1 files changed, 50 insertions, 9 deletions
diff --git a/src/host/buildvm_asm.c b/src/host/buildvm_asm.c index 000aaa38..28419c07 100644 --- a/src/host/buildvm_asm.c +++ b/src/host/buildvm_asm.c | |||
@@ -51,8 +51,8 @@ static const char *const jccnames[] = { | |||
51 | "js", "jns", "jpe", "jpo", "jl", "jge", "jle", "jg" | 51 | "js", "jns", "jpe", "jpo", "jl", "jge", "jle", "jg" |
52 | }; | 52 | }; |
53 | 53 | ||
54 | /* Emit relocation for the incredibly stupid OSX assembler. */ | 54 | /* Emit x86/x64 text relocations. */ |
55 | static void emit_asm_reloc_mach(BuildCtx *ctx, uint8_t *cp, int n, | 55 | static void emit_asm_reloc_text(BuildCtx *ctx, uint8_t *cp, int n, |
56 | const char *sym) | 56 | const char *sym) |
57 | { | 57 | { |
58 | const char *opname = NULL; | 58 | const char *opname = NULL; |
@@ -71,6 +71,20 @@ err: | |||
71 | exit(1); | 71 | exit(1); |
72 | } | 72 | } |
73 | emit_asm_bytes(ctx, cp, n); | 73 | emit_asm_bytes(ctx, cp, n); |
74 | if (strncmp(sym+(*sym == '_'), LABEL_PREFIX, sizeof(LABEL_PREFIX)-1)) { | ||
75 | /* Various fixups for external symbols outside of our binary. */ | ||
76 | if (ctx->mode == BUILD_elfasm) { | ||
77 | if (LJ_32) | ||
78 | fprintf(ctx->fp, "#if __PIC__\n\t%s lj_wrap_%s\n#else\n", opname, sym); | ||
79 | fprintf(ctx->fp, "\t%s %s@PLT\n", opname, sym); | ||
80 | if (LJ_32) | ||
81 | fprintf(ctx->fp, "#endif\n"); | ||
82 | return; | ||
83 | } else if (LJ_32 && ctx->mode == BUILD_machasm) { | ||
84 | fprintf(ctx->fp, "\t%s L%s$stub\n", opname, sym); | ||
85 | return; | ||
86 | } | ||
87 | } | ||
74 | fprintf(ctx->fp, "\t%s %s\n", opname, sym); | 88 | fprintf(ctx->fp, "\t%s %s\n", opname, sym); |
75 | } | 89 | } |
76 | #else | 90 | #else |
@@ -107,7 +121,16 @@ static void emit_asm_wordreloc(BuildCtx *ctx, uint8_t *p, int n, | |||
107 | ins, sym); | 121 | ins, sym); |
108 | exit(1); | 122 | exit(1); |
109 | } | 123 | } |
110 | #elif LJ_TARGET_PPC || LJ_TARGET_PPCSPE | 124 | #elif LJ_TARGET_ARM64 |
125 | if ((ins >> 26) == 0x25u) { | ||
126 | fprintf(ctx->fp, "\tbl %s\n", sym); | ||
127 | } else { | ||
128 | fprintf(stderr, | ||
129 | "Error: unsupported opcode %08x for %s symbol relocation.\n", | ||
130 | ins, sym); | ||
131 | exit(1); | ||
132 | } | ||
133 | #elif LJ_TARGET_PPC | ||
111 | #if LJ_TARGET_PS3 | 134 | #if LJ_TARGET_PS3 |
112 | #define TOCPREFIX "." | 135 | #define TOCPREFIX "." |
113 | #else | 136 | #else |
@@ -117,6 +140,14 @@ static void emit_asm_wordreloc(BuildCtx *ctx, uint8_t *p, int n, | |||
117 | fprintf(ctx->fp, "\t%s %d, %d, " TOCPREFIX "%s\n", | 140 | fprintf(ctx->fp, "\t%s %d, %d, " TOCPREFIX "%s\n", |
118 | (ins & 1) ? "bcl" : "bc", (ins >> 21) & 31, (ins >> 16) & 31, sym); | 141 | (ins & 1) ? "bcl" : "bc", (ins >> 21) & 31, (ins >> 16) & 31, sym); |
119 | } else if ((ins >> 26) == 18) { | 142 | } else if ((ins >> 26) == 18) { |
143 | #if LJ_ARCH_PPC64 | ||
144 | const char *suffix = strchr(sym, '@'); | ||
145 | if (suffix && suffix[1] == 'h') { | ||
146 | fprintf(ctx->fp, "\taddis 11, 2, %s\n", sym); | ||
147 | } else if (suffix && suffix[1] == 'l') { | ||
148 | fprintf(ctx->fp, "\tld 12, %s\n", sym); | ||
149 | } else | ||
150 | #endif | ||
120 | fprintf(ctx->fp, "\t%s " TOCPREFIX "%s\n", (ins & 1) ? "bl" : "b", sym); | 151 | fprintf(ctx->fp, "\t%s " TOCPREFIX "%s\n", (ins & 1) ? "bl" : "b", sym); |
121 | } else { | 152 | } else { |
122 | fprintf(stderr, | 153 | fprintf(stderr, |
@@ -214,6 +245,9 @@ void emit_asm(BuildCtx *ctx) | |||
214 | int i, rel; | 245 | int i, rel; |
215 | 246 | ||
216 | fprintf(ctx->fp, "\t.file \"buildvm_%s.dasc\"\n", ctx->dasm_arch); | 247 | fprintf(ctx->fp, "\t.file \"buildvm_%s.dasc\"\n", ctx->dasm_arch); |
248 | #if LJ_ARCH_PPC64 | ||
249 | fprintf(ctx->fp, "\t.abiversion 2\n"); | ||
250 | #endif | ||
217 | fprintf(ctx->fp, "\t.text\n"); | 251 | fprintf(ctx->fp, "\t.text\n"); |
218 | emit_asm_align(ctx, 4); | 252 | emit_asm_align(ctx, 4); |
219 | 253 | ||
@@ -227,11 +261,20 @@ void emit_asm(BuildCtx *ctx) | |||
227 | 261 | ||
228 | #if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND | 262 | #if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND |
229 | /* This should really be moved into buildvm_arm.dasc. */ | 263 | /* This should really be moved into buildvm_arm.dasc. */ |
264 | #if LJ_ARCH_HASFPU | ||
265 | fprintf(ctx->fp, | ||
266 | ".fnstart\n" | ||
267 | ".save {r5, r6, r7, r8, r9, r10, r11, lr}\n" | ||
268 | ".vsave {d8-d15}\n" | ||
269 | ".save {r4}\n" | ||
270 | ".pad #28\n"); | ||
271 | #else | ||
230 | fprintf(ctx->fp, | 272 | fprintf(ctx->fp, |
231 | ".fnstart\n" | 273 | ".fnstart\n" |
232 | ".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n" | 274 | ".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n" |
233 | ".pad #28\n"); | 275 | ".pad #28\n"); |
234 | #endif | 276 | #endif |
277 | #endif | ||
235 | #if LJ_TARGET_MIPS | 278 | #if LJ_TARGET_MIPS |
236 | fprintf(ctx->fp, ".set nomips16\n.abicalls\n.set noreorder\n.set nomacro\n"); | 279 | fprintf(ctx->fp, ".set nomips16\n.abicalls\n.set noreorder\n.set nomacro\n"); |
237 | #endif | 280 | #endif |
@@ -254,8 +297,9 @@ void emit_asm(BuildCtx *ctx) | |||
254 | BuildReloc *r = &ctx->reloc[rel]; | 297 | BuildReloc *r = &ctx->reloc[rel]; |
255 | int n = r->ofs - ofs; | 298 | int n = r->ofs - ofs; |
256 | #if LJ_TARGET_X86ORX64 | 299 | #if LJ_TARGET_X86ORX64 |
257 | if (ctx->mode == BUILD_machasm && r->type != 0) { | 300 | if (r->type != 0 && |
258 | emit_asm_reloc_mach(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]); | 301 | (ctx->mode == BUILD_elfasm || ctx->mode == BUILD_machasm)) { |
302 | emit_asm_reloc_text(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]); | ||
259 | } else { | 303 | } else { |
260 | emit_asm_bytes(ctx, ctx->code+ofs, n); | 304 | emit_asm_bytes(ctx, ctx->code+ofs, n); |
261 | emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]); | 305 | emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]); |
@@ -289,10 +333,7 @@ void emit_asm(BuildCtx *ctx) | |||
289 | #if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA) | 333 | #if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA) |
290 | fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n"); | 334 | fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n"); |
291 | #endif | 335 | #endif |
292 | #if LJ_TARGET_PPCSPE | 336 | #if LJ_TARGET_PPC && !LJ_TARGET_PS3 |
293 | /* Soft-float ABI + SPE. */ | ||
294 | fprintf(ctx->fp, "\t.gnu_attribute 4, 2\n\t.gnu_attribute 8, 3\n"); | ||
295 | #elif LJ_TARGET_PPC && !LJ_TARGET_PS3 | ||
296 | /* Hard-float ABI. */ | 337 | /* Hard-float ABI. */ |
297 | fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n"); | 338 | fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n"); |
298 | #endif | 339 | #endif |