diff options
| -rw-r--r-- | asm.peg | 12 | ||||
| -rw-r--r-- | main.c | 14 | ||||
| -rw-r--r-- | test/test.sh | 2 |
3 files changed, 14 insertions, 14 deletions
@@ -256,13 +256,13 @@ imul = "imul" ( | 'l'? ws s:mem ws? ',' ws? d:r32 { $$ = MEMREG({.w=0}, -1, 0x01000faf, s, d); } | 'q'? ws s:mem ws? ',' ws? d:r64 { $$ = MEMREG({.w=1}, -1, 0x01000faf, s, d); } - | 'w'? ws i:imm16 ws? ',' ws? s:r16 ws? ',' ws? d:r16 { $$ = IMMREGREG2({.w=0}, 0x66, 0x69, i, s, d); } - | 'l'? ws i:imm32 ws? ',' ws? s:r32 ws? ',' ws? d:r32 { $$ = IMMREGREG2({.w=0}, -1, 0x69, i, s, d); } - | 'q'? ws i:imm32 ws? ',' ws? s:r64 ws? ',' ws? d:r64 { $$ = IMMREGREG2({.w=1}, -1, 0x69, i, s, d); } + | 'w'? ws i:imm16-8 ws? ',' ws? s:r16 ws? ',' ws? d:r16 { $$ = IMMREGREG2({.w=0}, 0x66, i.imm.nbytes == 1 ? 0x6b : 0x69, i, s, d); } + | 'l'? ws i:imm32-8 ws? ',' ws? s:r32 ws? ',' ws? d:r32 { $$ = IMMREGREG2({.w=0}, -1, i.imm.nbytes == 1 ? 0x6b : 0x69, i, s, d); } + | 'q'? ws i:imm32-8 ws? ',' ws? s:r64 ws? ',' ws? d:r64 { $$ = IMMREGREG2({.w=1}, -1, i.imm.nbytes == 1 ? 0x6b : 0x69, i, s, d); } - | 'w'? ws i:imm16 ws? ',' ws? s:mem ws? ',' ws? d:r16 { $$ = IMMMEMREG({.w=0}, 0x66, 0x69, i, s, d); } - | 'l'? ws i:imm32 ws? ',' ws? s:mem ws? ',' ws? d:r32 { $$ = IMMMEMREG({.w=0}, -1, 0x69, i, s, d); } - | 'q'? ws i:imm32 ws? ',' ws? s:mem ws? ',' ws? d:r64 { $$ = IMMMEMREG({.w=1}, -1, 0x69, i, s, d); } + | 'w'? ws i:imm16-8 ws? ',' ws? s:mem ws? ',' ws? d:r16 { $$ = IMMMEMREG({.w=0}, 0x66, i.imm.nbytes == 1 ? 0x6b : 0x69, i, s, d); } + | 'l'? ws i:imm32-8 ws? ',' ws? s:mem ws? ',' ws? d:r32 { $$ = IMMMEMREG({.w=0}, -1, i.imm.nbytes == 1 ? 0x6b : 0x69, i, s, d); } + | 'q'? ws i:imm32-8 ws? ',' ws? s:mem ws? ',' ws? d:r64 { $$ = IMMMEMREG({.w=1}, -1, i.imm.nbytes == 1 ? 0x6b : 0x69, i, s, d); } # Must come last due to peg ordering. | 'b' ws a:mem { $$ = OPMEM({.w=0}, -1, 0xf6, 0x05, a); } @@ -395,14 +395,12 @@ assemblemem(const Memarg* memarg, Rex rex, VarBytes prefix, VarBytes opcode, /* Case when we don't need sib */ if (memarg->index == ASM_NO_REG && memarg->scale == 0 && ((rm & 7) != 4)) { - if (memarg->disp.l == 0 && memarg->disp.c == 0) { - if ((rm & 7) == 5) { - mod = 1; - } else { - mod = 0; - } - } else { + if (memarg->disp.l != NULL || memarg->disp.c > INT8_MAX || memarg->disp.c < INT8_MIN) { mod = 2; + } else if (memarg->disp.c != 0 || (rm & 7) == 5) { + mod = 1; + } else { + mod = 0; } assemblevbytes(prefix); @@ -505,7 +503,7 @@ assemblejmp(const Jmp* j) } else { distance = target->wco - cursection->hdr.sh_size; } - if ((distance - 1) >= -128 && (distance - 1) <= 127) { + if ((distance - 1) >= -128 && (distance - 5) <= 127) { jmpsize = 1; } else { jmpsize = 4; diff --git a/test/test.sh b/test/test.sh index 152ea2b..5536d61 100644 --- a/test/test.sh +++ b/test/test.sh @@ -43,6 +43,8 @@ t "callq *%rax" t "callq *%r10" t "callq *(%r10)" t "movb %r11b, (%rsi, %r12, 1)" +t "mov %rdi, -0x60(%rbp)" +t "imul \$0x28, %rbx, %rcx" for r in rax r10 do |
