aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/buildvm_asm.c56
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. */
12static void emit_asm_bytes(BuildCtx *ctx, uint8_t *p, int n) 13static 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. */
78static 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. */
92static 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. */
77static void emit_asm_label(BuildCtx *ctx, const char *name, int size, int isfunc) 117static 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);