aboutsummaryrefslogtreecommitdiff
path: root/dynasm/dasm_x86.h
diff options
context:
space:
mode:
Diffstat (limited to 'dynasm/dasm_x86.h')
-rw-r--r--dynasm/dasm_x86.h38
1 files changed, 32 insertions, 6 deletions
diff --git a/dynasm/dasm_x86.h b/dynasm/dasm_x86.h
index 84b9d17f..edaddf54 100644
--- a/dynasm/dasm_x86.h
+++ b/dynasm/dasm_x86.h
@@ -170,7 +170,7 @@ void dasm_put(Dst_DECL, int start, ...)
170 dasm_State *D = Dst_REF; 170 dasm_State *D = Dst_REF;
171 dasm_ActList p = D->actionlist + start; 171 dasm_ActList p = D->actionlist + start;
172 dasm_Section *sec = D->section; 172 dasm_Section *sec = D->section;
173 int pos = sec->pos, ofs = sec->ofs, mrm = 4; 173 int pos = sec->pos, ofs = sec->ofs, mrm = -1;
174 int *b; 174 int *b;
175 175
176 if (pos >= sec->epos) { 176 if (pos >= sec->epos) {
@@ -193,7 +193,7 @@ void dasm_put(Dst_DECL, int start, ...)
193 b[pos++] = n; 193 b[pos++] = n;
194 switch (action) { 194 switch (action) {
195 case DASM_DISP: 195 case DASM_DISP:
196 if (n == 0) { if ((mrm&7) == 4) mrm = p[-2]; if ((mrm&7) != 5) break; } 196 if (n == 0) { if (mrm < 0) mrm = p[-2]; if ((mrm&7) != 5) break; }
197 /* fallthrough */ 197 /* fallthrough */
198 case DASM_IMM_DB: if (((n+128)&-256) == 0) goto ob; /* fallthrough */ 198 case DASM_IMM_DB: if (((n+128)&-256) == 0) goto ob; /* fallthrough */
199 case DASM_REL_A: /* Assumes ptrdiff_t is int. !x64 */ 199 case DASM_REL_A: /* Assumes ptrdiff_t is int. !x64 */
@@ -204,11 +204,17 @@ void dasm_put(Dst_DECL, int start, ...)
204 case DASM_IMM_W: CK((n&-65536) == 0, RANGE_I); ofs += 2; break; 204 case DASM_IMM_W: CK((n&-65536) == 0, RANGE_I); ofs += 2; break;
205 case DASM_SPACE: p++; ofs += n; break; 205 case DASM_SPACE: p++; ofs += n; break;
206 case DASM_SETLABEL: b[pos-2] = -0x40000000; break; /* Neg. label ofs. */ 206 case DASM_SETLABEL: b[pos-2] = -0x40000000; break; /* Neg. label ofs. */
207 case DASM_VREG: CK((n&-8) == 0 && (n != 4 || (*p&1) == 0), RANGE_VREG); 207 case DASM_VREG: CK((n&-16) == 0 && (n != 4 || (*p>>5) != 2), RANGE_VREG);
208 if (*p++ == 1 && *p == DASM_DISP) mrm = n; 208 if (*p < 0x40 && p[1] == DASM_DISP) mrm = n;
209 if (*p < 0x20 && (n&7) == 4) ofs++;
210 switch ((*p++ >> 3) & 3) {
211 case 3: n |= b[pos-3]; /* fallthrough */
212 case 2: n |= b[pos-2]; /* fallthrough */
213 case 1: if (n <= 7) { b[pos-1] |= 0x10; ofs--; }
214 }
209 continue; 215 continue;
210 } 216 }
211 mrm = 4; 217 mrm = -1;
212 } else { 218 } else {
213 int *pl, n; 219 int *pl, n;
214 switch (action) { 220 switch (action) {
@@ -399,7 +405,27 @@ int dasm_encode(Dst_DECL, void *buffer)
399 case DASM_IMM_WB: if (((n+128)&-256) == 0) goto db; else mark = NULL; 405 case DASM_IMM_WB: if (((n+128)&-256) == 0) goto db; else mark = NULL;
400 /* fallthrough */ 406 /* fallthrough */
401 case DASM_IMM_W: dasmw(n); break; 407 case DASM_IMM_W: dasmw(n); break;
402 case DASM_VREG: { int t = *p++; if (t >= 2) n<<=3; cp[-1] |= n; break; } 408 case DASM_VREG: {
409 int t = *p++;
410 unsigned char *ex = cp - (t&7);
411 if ((n & 8) && t < 0xa0) {
412 if (*ex & 0x80) ex[1] ^= 0x20 << (t>>6); else *ex ^= 1 << (t>>6);
413 n &= 7;
414 } else if (n & 0x10) {
415 if (*ex & 0x80) {
416 *ex = 0xc5; ex[1] = (ex[1] & 0x80) | ex[2]; ex += 2;
417 }
418 while (++ex < cp) ex[-1] = *ex;
419 if (mark) mark--;
420 cp--;
421 n &= 7;
422 }
423 if (t >= 0xc0) n <<= 4;
424 else if (t >= 0x40) n <<= 3;
425 else if (n == 4 && t < 0x20) { cp[-1] ^= n; *cp++ = 0x20; }
426 cp[-1] ^= n;
427 break;
428 }
403 case DASM_REL_LG: p++; if (n >= 0) goto rel_pc; 429 case DASM_REL_LG: p++; if (n >= 0) goto rel_pc;
404 b++; n = (int)(ptrdiff_t)D->globals[-n]; 430 b++; n = (int)(ptrdiff_t)D->globals[-n];
405 /* fallthrough */ 431 /* fallthrough */