mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-03-01 17:35:38 +08:00
Same some space by introducing shorthand byte codes for SSE prefixes
Properly done, all SSE instructions which has the 66/F2/F3 opcode multiplex need two prefixes: one to control the use of OSP and one to control the use of REP. However, it's a four-way select: np/66/F2/F3; so introduce shorthand bytecodes for that purpose.
This commit is contained in:
parent
24860b0f0e
commit
fff5a47e65
27
assemble.c
27
assemble.c
@ -91,6 +91,10 @@
|
||||
* \335 - disassemble a rep (0xF3 byte) prefix as repe not rep.
|
||||
* \340 - reserve <operand 0> bytes of uninitialized storage.
|
||||
* Operand 0 had better be a segmentless constant.
|
||||
* \360 - no SSE prefix (== \364\331)
|
||||
* \361 - 66 SSE prefix (== \366\331)
|
||||
* \362 - F2 SSE prefix (== \364\332)
|
||||
* \363 - F3 SSE prefix (== \364\333)
|
||||
* \364 - operand-size prefix (0x66) not permitted
|
||||
* \365 - address-size prefix (0x67) not permitted
|
||||
* \366 - operand-size prefix (0x66) used as opcode extension
|
||||
@ -1077,6 +1081,13 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
|
||||
else
|
||||
length += ins->oprs[0].offset;
|
||||
break;
|
||||
case 0360:
|
||||
break;
|
||||
case 0361:
|
||||
case 0362:
|
||||
case 0363:
|
||||
length++;
|
||||
break;
|
||||
case 0364:
|
||||
case 0365:
|
||||
break;
|
||||
@ -1732,6 +1743,22 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
}
|
||||
break;
|
||||
|
||||
case 0360:
|
||||
break;
|
||||
|
||||
case 0361:
|
||||
bytes[0] = 0x66;
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
break;
|
||||
|
||||
case 0362:
|
||||
case 0363:
|
||||
bytes[0] = c - 0362 + 0xf2;
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
break;
|
||||
|
||||
case 0364:
|
||||
case 0365:
|
||||
break;
|
||||
|
20
disasm.c
20
disasm.c
@ -874,6 +874,26 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
case 0340:
|
||||
return false;
|
||||
|
||||
case 0360:
|
||||
if (prefix->osp || prefix->rep)
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 0361:
|
||||
if (!prefix->osp || prefix->rep)
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 0362:
|
||||
if (prefix->osp || prefix->rep != 0xf2)
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 0363:
|
||||
if (prefix->osp || prefix->rep != 0xf3)
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 0364:
|
||||
if (prefix->osp)
|
||||
return false;
|
||||
|
10
insns.pl
10
insns.pl
@ -539,13 +539,13 @@ sub byte_code_compile($) {
|
||||
} elsif ($prefix_ok && $op =~ /^(66|f2|f3|np)$/) {
|
||||
# 66/F2/F3 prefix used as an opcode extension, or np = no prefix
|
||||
if ($op eq '66') {
|
||||
push(@codes, 0366, 0331);
|
||||
push(@codes, 0361);
|
||||
} elsif ($op eq 'f2') {
|
||||
push(@codes, 0332, 0364);
|
||||
push(@codes, 0362);
|
||||
} elsif ($op eq 'f3') {
|
||||
push(@codes, 0333, 0364);
|
||||
push(@codes, 0363);
|
||||
} else {
|
||||
push(@codes, 0331, 0364);
|
||||
push(@codes, 0360);
|
||||
}
|
||||
} elsif ($op =~ /^[0-9a-f]{2}$/) {
|
||||
if (defined($litix) && $litix+$codes[$litix]+1 == scalar @codes) {
|
||||
@ -678,6 +678,7 @@ sub byte_code_compile($) {
|
||||
die "$0: $line: $op without 'i' and 's' operands\n";
|
||||
}
|
||||
push(@codes, 0172, ($oppos{'s'} << 3)+$oppos{'i'});
|
||||
$prefix_ok = 0;
|
||||
} elsif ($op =~ /^(is4|imz2)\=([0-9]+)$/) {
|
||||
my $imm = $2;
|
||||
if (!defined($oppos{'s'})) {
|
||||
@ -687,6 +688,7 @@ sub byte_code_compile($) {
|
||||
die "$0: $line: invalid imm4 value for $op: $imm\n";
|
||||
}
|
||||
push(@codes, 0173, ($oppos{'s'} << 4) + $imm);
|
||||
$prefix_ok = 0;
|
||||
} elsif ($op =~ /^([0-9a-f]{2})\+s$/) {
|
||||
if (!defined($oppos{'i'})) {
|
||||
die "$0: $op without 'i' operand\n";
|
||||
|
Loading…
Reference in New Issue
Block a user