summaryrefslogtreecommitdiff
path: root/assemble.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-09-17 17:25:27 -0700
committerH. Peter Anvin <hpa@zytor.com>2007-09-17 17:25:27 -0700
commitcf5180a9553e43bbaa46fd1a77c75dc8b7f6da42 (patch)
treee49a78cca72852670b210bce53f4c5698fc4c7bf /assemble.c
parent401c07e20d14130a2d147468a408fce9edd1faff (diff)
downloadnasm-cf5180a9553e43bbaa46fd1a77c75dc8b7f6da42.tar.gz
nasm-cf5180a9553e43bbaa46fd1a77c75dc8b7f6da42.tar.bz2
nasm-cf5180a9553e43bbaa46fd1a77c75dc8b7f6da42.zip
Actually generate SSE5 instructions
This checkin completes what is required to actually generate SSE5 instructions. No support in the disassembler yet. This checkin covers: - Support for actually generating DREX prefixes. - Support for matching operand "operand X must match Y"
Diffstat (limited to 'assemble.c')
-rw-r--r--assemble.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/assemble.c b/assemble.c
index a140c72..ec3b112 100644
--- a/assemble.c
+++ b/assemble.c
@@ -856,6 +856,7 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
case 0163:
length++;
ins->rex |= REX_D;
+ ins->drexdst = regval(&ins->oprs[c & 3]);
break;
case 0164:
case 0165:
@@ -863,6 +864,7 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
case 0167:
length++;
ins->rex |= REX_D|REX_OC;
+ ins->drexdst = regval(&ins->oprs[c & 3]);
break;
case 0170:
length++;
@@ -974,6 +976,11 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
errfunc(ERR_NONFATAL, "cannot use high register in drex instruction");
return -1;
}
+ if (bits != 64 && ((ins->rex & (REX_W|REX_X|REX_B)) ||
+ ins->drexdst > 7)) {
+ errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
+ return -1;
+ }
length++;
} else if (ins->rex & REX_REAL) {
if (ins->rex & REX_H) {
@@ -985,8 +992,8 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
cpu >= IF_X86_64)) {
length++;
} else {
- errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
- return -1;
+ errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
+ return -1;
}
}
@@ -1358,7 +1365,6 @@ static void gencode(int32_t segment, int32_t offset, int bits,
case 0165:
case 0166:
case 0167:
- ins->drexdst = regval(&ins->oprs[c & 3]);
break;
case 0170:
@@ -1663,7 +1669,12 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
* Check that the operand flags all match up
*/
for (i = 0; i < itemp->operands; i++) {
- if (itemp->opd[i] & ~instruction->oprs[i].type ||
+ if (itemp->opd[i] & SAME_AS) {
+ int j = itemp->opd[i] & ~SAME_AS;
+ if (instruction->oprs[i].type != instruction->oprs[j].type ||
+ instruction->oprs[i].basereg != instruction->oprs[j].basereg)
+ return 0;
+ } else if (itemp->opd[i] & ~instruction->oprs[i].type ||
((itemp->opd[i] & SIZE_MASK) &&
((itemp->opd[i] ^ instruction->oprs[i].type) & SIZE_MASK))) {
if ((itemp->opd[i] & ~instruction->oprs[i].type & ~SIZE_MASK) ||