mirror of
https://github.com/alliedmodders/sourcemod.git
synced 2025-12-07 02:18:35 +00:00
Add opcodes for sign-extending integers.
This commit is contained in:
parent
6f0242387a
commit
4684cd5bac
@ -367,6 +367,7 @@ class AssemblerX86 : public Assembler
|
||||
void movb(Register dest, const Operand &src) {
|
||||
emit1(0x8a, dest.code, src);
|
||||
}
|
||||
|
||||
void movzxb(Register dest, const Operand &src) {
|
||||
emit2(0x0f, 0xb6, dest.code, src);
|
||||
}
|
||||
@ -380,6 +381,24 @@ class AssemblerX86 : public Assembler
|
||||
emit2(0x0f, 0xb7, dest.code, src.code);
|
||||
}
|
||||
|
||||
void movsxb(Register dest, const Operand &src) {
|
||||
emit2(0x0f, 0xbe, dest.code, src);
|
||||
}
|
||||
void movsxb(Register dest, const Register src) {
|
||||
emit2(0x0f, 0xbe, dest.code, src.code);
|
||||
}
|
||||
void movsxw(Register dest, const Operand &src) {
|
||||
emit2(0x0f, 0xbf, dest.code, src);
|
||||
}
|
||||
void movsxw(Register dest, const Register src) {
|
||||
emit2(0x0f, 0xbf, dest.code, src.code);
|
||||
}
|
||||
|
||||
// Sign extend eax -> edx.
|
||||
void cdq() {
|
||||
emit1(0x99);
|
||||
}
|
||||
|
||||
void lea(Register dest, const Operand &src) {
|
||||
emit1(0x8d, dest.code, src);
|
||||
}
|
||||
|
||||
@ -432,8 +432,8 @@ static OPCODEC opcodelist[] = {
|
||||
{ 66, "shr", sIN_CSEG, parm0 },
|
||||
{ 71, "shr.c.alt", sIN_CSEG, parm1 },
|
||||
{ 70, "shr.c.pri", sIN_CSEG, parm1 },
|
||||
{ 94, "sign.alt", sIN_CSEG, parm0 },
|
||||
{ 93, "sign.pri", sIN_CSEG, parm0 },
|
||||
{ 94, "sign.alt", sIN_CSEG, parm1 },
|
||||
{ 93, "sign.pri", sIN_CSEG, parm1 },
|
||||
{102, "sleq", sIN_CSEG, parm0 },
|
||||
{101, "sless", sIN_CSEG, parm0 },
|
||||
{ 72, "smul", sIN_CSEG, parm0 },
|
||||
|
||||
@ -161,8 +161,8 @@ namespace sp {
|
||||
_(ZERO_ALT, "zero.alt") \
|
||||
_(ZERO, "zero") \
|
||||
_(ZERO_S, "zero.s") \
|
||||
_(UNGEN_SIGN_PRI, "sign.pri") \
|
||||
_(UNGEN_SIGN_ALT, "sign.alt") \
|
||||
_(SIGN_PRI, "sign.pri") \
|
||||
_(SIGN_ALT, "sign.alt") \
|
||||
_(EQ, "eq") \
|
||||
_(NEQ, "neq") \
|
||||
_(LESS, "less") \
|
||||
|
||||
@ -980,6 +980,41 @@ Compiler::emitOp(OPCODE op)
|
||||
__ sarl(pri, 2);
|
||||
break;
|
||||
|
||||
// Sign extend an [8,16] bit value to a 32-bit value, or a 32-bit value
|
||||
// to a 64-bit value.
|
||||
case OP_SIGN_PRI:
|
||||
case OP_SIGN_ALT:
|
||||
{
|
||||
Register reg = (op == OP_SIGN_PRI) ? pri : alt;
|
||||
size_t bits = readCell();
|
||||
switch (bits) {
|
||||
case 8:
|
||||
__ movsxb(reg, reg);
|
||||
break;
|
||||
case 16:
|
||||
__ movsxw(reg, reg);
|
||||
break;
|
||||
case 32:
|
||||
// Address is in |reg|. We have to save pri/alt because cdq needs
|
||||
// to destroy both. We move the sign-extended reg to ecx and then
|
||||
// write it back after.
|
||||
emitCheckAddress(reg);
|
||||
__ push(eax);
|
||||
__ push(edx);
|
||||
__ movl(tmp, Operand(reg, 0));
|
||||
__ cdq();
|
||||
__ movl(tmp, edx);
|
||||
__ pop(edx);
|
||||
__ pop(eax);
|
||||
__ movl(Operand(reg, 4), tmp);
|
||||
break;
|
||||
default:
|
||||
error_= SP_ERROR_INVALID_INSTRUCTION;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_ABS_F32:
|
||||
__ movl(pri, Operand(stk, 0));
|
||||
__ andl(pri, 0x7fffffff);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user