diff options
-rw-r--r-- | src/buildvm_asm.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/buildvm_asm.c b/src/buildvm_asm.c index 1898f0d5..31ecc2e2 100644 --- a/src/buildvm_asm.c +++ b/src/buildvm_asm.c | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | /* ------------------------------------------------------------------------ */ | 9 | /* ------------------------------------------------------------------------ */ |
10 | 10 | ||
11 | #if LJ_TARGET_X86ORX64 | ||
11 | /* Emit bytes piecewise as assembler text. */ | 12 | /* Emit bytes piecewise as assembler text. */ |
12 | static void emit_asm_bytes(BuildCtx *ctx, uint8_t *p, int n) | 13 | static void emit_asm_bytes(BuildCtx *ctx, uint8_t *p, int n) |
13 | { | 14 | { |
@@ -72,6 +73,45 @@ err: | |||
72 | emit_asm_bytes(ctx, cp, n); | 73 | emit_asm_bytes(ctx, cp, n); |
73 | fprintf(ctx->fp, "\t%s %s\n", opname, sym); | 74 | fprintf(ctx->fp, "\t%s %s\n", opname, sym); |
74 | } | 75 | } |
76 | #else | ||
77 | /* Emit words piecewise as assembler text. */ | ||
78 | static void emit_asm_words(BuildCtx *ctx, uint8_t *p, int n) | ||
79 | { | ||
80 | int i; | ||
81 | for (i = 0; i < n; i += 4) { | ||
82 | if ((i & 15) == 0) | ||
83 | fprintf(ctx->fp, "\t.long 0x%08x", *(uint32_t *)(p+i)); | ||
84 | else | ||
85 | fprintf(ctx->fp, ",0x%08x", *(uint32_t *)(p+i)); | ||
86 | if ((i & 15) == 12) putc('\n', ctx->fp); | ||
87 | } | ||
88 | if ((n & 15) != 0) putc('\n', ctx->fp); | ||
89 | } | ||
90 | |||
91 | /* Emit relocation as part of an instruction. */ | ||
92 | static void emit_asm_wordreloc(BuildCtx *ctx, uint8_t *p, int n, | ||
93 | const char *sym) | ||
94 | { | ||
95 | uint32_t ins; | ||
96 | emit_asm_words(ctx, p, n-4); | ||
97 | ins = *(uint32_t *)(p+n-4); | ||
98 | #if LJ_TARGET_PPC | ||
99 | if ((ins >> 26) == 16) { | ||
100 | fprintf(ctx->fp, "\t%s %d, %d, %s\n", | ||
101 | (ins & 1) ? "bcl" : "bc", (ins >> 21) & 31, (ins >> 16) & 31, sym); | ||
102 | } else if ((ins >> 26) == 18) { | ||
103 | fprintf(ctx->fp, "\t%s %s\n", (ins & 1) ? "bl" : "b", sym); | ||
104 | } else { | ||
105 | fprintf(stderr, | ||
106 | "Error: unsupported opcode %08x for %s symbol relocation.\n", | ||
107 | ins, sym); | ||
108 | exit(1); | ||
109 | } | ||
110 | #else | ||
111 | #error "missing relocation support for this architecture" | ||
112 | #endif | ||
113 | } | ||
114 | #endif | ||
75 | 115 | ||
76 | /* Emit an assembler label. */ | 116 | /* Emit an assembler label. */ |
77 | static void emit_asm_label(BuildCtx *ctx, const char *name, int size, int isfunc) | 117 | static void emit_asm_label(BuildCtx *ctx, const char *name, int size, int isfunc) |
@@ -140,6 +180,7 @@ void emit_asm(BuildCtx *ctx) | |||
140 | while (rel < ctx->nreloc && ctx->reloc[rel].ofs < next) { | 180 | while (rel < ctx->nreloc && ctx->reloc[rel].ofs < next) { |
141 | BuildReloc *r = &ctx->reloc[rel]; | 181 | BuildReloc *r = &ctx->reloc[rel]; |
142 | int n = r->ofs - ofs; | 182 | int n = r->ofs - ofs; |
183 | #if LJ_TARGET_X86ORX64 | ||
143 | if (ctx->mode == BUILD_machasm && r->type != 0) { | 184 | if (ctx->mode == BUILD_machasm && r->type != 0) { |
144 | emit_asm_reloc_mach(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]); | 185 | emit_asm_reloc_mach(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]); |
145 | } else { | 186 | } else { |
@@ -147,15 +188,30 @@ void emit_asm(BuildCtx *ctx) | |||
147 | emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]); | 188 | emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]); |
148 | } | 189 | } |
149 | ofs += n+4; | 190 | ofs += n+4; |
191 | #else | ||
192 | emit_asm_wordreloc(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]); | ||
193 | ofs += n; | ||
194 | #endif | ||
150 | rel++; | 195 | rel++; |
151 | } | 196 | } |
197 | #if LJ_TARGET_X86ORX64 | ||
152 | emit_asm_bytes(ctx, ctx->code+ofs, next-ofs); | 198 | emit_asm_bytes(ctx, ctx->code+ofs, next-ofs); |
199 | #else | ||
200 | emit_asm_words(ctx, ctx->code+ofs, next-ofs); | ||
201 | #endif | ||
153 | } | 202 | } |
154 | 203 | ||
155 | fprintf(ctx->fp, "\n"); | 204 | fprintf(ctx->fp, "\n"); |
156 | switch (ctx->mode) { | 205 | switch (ctx->mode) { |
157 | case BUILD_elfasm: | 206 | case BUILD_elfasm: |
158 | fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\",@progbits\n"); | 207 | fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\",@progbits\n"); |
208 | #if LJ_TARGET_PPCSPE | ||
209 | /* Soft-float ABI + SPE. */ | ||
210 | fprintf(ctx->fp, "\t.gnu_attribute 4, 2\n\t.gnu_attribute 8, 3\n"); | ||
211 | #elif LJ_TARGET_PPC | ||
212 | /* Hard-float ABI. */ | ||
213 | fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n"); | ||
214 | #endif | ||
159 | /* fallthrough */ | 215 | /* fallthrough */ |
160 | case BUILD_coffasm: | 216 | case BUILD_coffasm: |
161 | fprintf(ctx->fp, "\t.ident \"%s\"\n", ctx->dasm_ident); | 217 | fprintf(ctx->fp, "\t.ident \"%s\"\n", ctx->dasm_ident); |