mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
More AVX instructions ({ADD,SUB,MUL,DIV}{SS,SD}rm)
Introduce the VEX_X field llvm-svn: 105859
This commit is contained in:
parent
d9120853e1
commit
69141fd639
@ -704,6 +704,24 @@ multiclass basic_sse12_fp_binop_rm<bits<8> opc, string OpcodeStr,
|
|||||||
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
!strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
|
||||||
[(set FR64:$dst, (OpNode FR64:$src1, (load addr:$src2)))]>;
|
[(set FR64:$dst, (OpNode FR64:$src1, (load addr:$src2)))]>;
|
||||||
|
|
||||||
|
def V#NAME#SSrm : VSSI<opc, MRMSrcMem, (outs FR32:$dst),
|
||||||
|
(ins FR32:$src1, f32mem:$src2),
|
||||||
|
!strconcat(OpcodeStr,
|
||||||
|
"ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
|
||||||
|
[]> {
|
||||||
|
let Constraints = "";
|
||||||
|
let isAsmParserOnly = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
def V#NAME#SDrm : VSDI<opc, MRMSrcMem, (outs FR64:$dst),
|
||||||
|
(ins FR64:$src1, f64mem:$src2),
|
||||||
|
!strconcat(OpcodeStr,
|
||||||
|
"sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
|
||||||
|
[]> {
|
||||||
|
let Constraints = "";
|
||||||
|
let isAsmParserOnly = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Vector operation, reg+reg.
|
// Vector operation, reg+reg.
|
||||||
def PSrr : PSI<opc, MRMSrcReg, (outs VR128:$dst),
|
def PSrr : PSI<opc, MRMSrcReg, (outs VR128:$dst),
|
||||||
(ins VR128:$src1, VR128:$src2),
|
(ins VR128:$src1, VR128:$src2),
|
||||||
|
@ -349,6 +349,13 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
|||||||
//
|
//
|
||||||
unsigned char VEX_R = 0x1;
|
unsigned char VEX_R = 0x1;
|
||||||
|
|
||||||
|
// VEX_X: equivalent to REX.X, only used when a
|
||||||
|
// register is used for index in SIB Byte.
|
||||||
|
//
|
||||||
|
// 1: Same as REX.X=0 (must be 1 in 32-bit mode)
|
||||||
|
// 0: Same as REX.X=1 (64-bit mode only)
|
||||||
|
unsigned char VEX_X = 0x1;
|
||||||
|
|
||||||
// VEX_B:
|
// VEX_B:
|
||||||
//
|
//
|
||||||
// 1: Same as REX_B=0 (ignored in 32-bit mode)
|
// 1: Same as REX_B=0 (ignored in 32-bit mode)
|
||||||
@ -415,9 +422,12 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
|||||||
unsigned NumOps = MI.getNumOperands();
|
unsigned NumOps = MI.getNumOperands();
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
unsigned SrcReg = 0, SrcRegNum = 0;
|
unsigned SrcReg = 0, SrcRegNum = 0;
|
||||||
|
bool IsSrcMem = false;
|
||||||
|
|
||||||
switch (TSFlags & X86II::FormMask) {
|
switch (TSFlags & X86II::FormMask) {
|
||||||
case X86II::MRMInitReg: assert(0 && "FIXME: Remove this!");
|
case X86II::MRMInitReg: assert(0 && "FIXME: Remove this!");
|
||||||
|
case X86II::MRMSrcMem:
|
||||||
|
IsSrcMem = true;
|
||||||
case X86II::MRMSrcReg:
|
case X86II::MRMSrcReg:
|
||||||
if (MI.getOperand(0).isReg() &&
|
if (MI.getOperand(0).isReg() &&
|
||||||
X86InstrInfo::isX86_64ExtendedReg(MI.getOperand(0).getReg()))
|
X86InstrInfo::isX86_64ExtendedReg(MI.getOperand(0).getReg()))
|
||||||
@ -447,6 +457,9 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
|||||||
const MCOperand &MO = MI.getOperand(i);
|
const MCOperand &MO = MI.getOperand(i);
|
||||||
if (MO.isReg() && X86InstrInfo::isX86_64ExtendedReg(MO.getReg()))
|
if (MO.isReg() && X86InstrInfo::isX86_64ExtendedReg(MO.getReg()))
|
||||||
VEX_B = 0x0;
|
VEX_B = 0x0;
|
||||||
|
if (!VEX_B && MO.isReg() && IsSrcMem &&
|
||||||
|
X86InstrInfo::isX86_64ExtendedReg(MO.getReg()))
|
||||||
|
VEX_X = 0x0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -464,11 +477,9 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
|||||||
// | C5h | | R | vvvv | L | pp |
|
// | C5h | | R | vvvv | L | pp |
|
||||||
// +-----+ +-------------------+
|
// +-----+ +-------------------+
|
||||||
//
|
//
|
||||||
// Note: VEX.X isn't used so far
|
|
||||||
//
|
|
||||||
unsigned char LastByte = VEX_PP | (VEX_L << 2) | (VEX_4V << 3);
|
unsigned char LastByte = VEX_PP | (VEX_L << 2) | (VEX_4V << 3);
|
||||||
|
|
||||||
if (VEX_B /* & VEX_X */) { // 2 byte VEX prefix
|
if (VEX_B && VEX_X) { // 2 byte VEX prefix
|
||||||
EmitByte(0xC5, CurByte, OS);
|
EmitByte(0xC5, CurByte, OS);
|
||||||
EmitByte(LastByte | (VEX_R << 7), CurByte, OS);
|
EmitByte(LastByte | (VEX_R << 7), CurByte, OS);
|
||||||
return;
|
return;
|
||||||
@ -476,7 +487,7 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
|||||||
|
|
||||||
// 3 byte VEX prefix
|
// 3 byte VEX prefix
|
||||||
EmitByte(0xC4, CurByte, OS);
|
EmitByte(0xC4, CurByte, OS);
|
||||||
EmitByte(VEX_R << 7 | 1 << 6 /* VEX_X = 1 */ | VEX_5M, CurByte, OS);
|
EmitByte(VEX_R << 7 | VEX_X << 6 | VEX_5M, CurByte, OS);
|
||||||
EmitByte(LastByte | (VEX_W << 7), CurByte, OS);
|
EmitByte(LastByte | (VEX_W << 7), CurByte, OS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,8 +762,13 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
|
|||||||
AddrOperands = X86AddrNumOperands - 1; // No segment register
|
AddrOperands = X86AddrNumOperands - 1; // No segment register
|
||||||
else
|
else
|
||||||
AddrOperands = X86AddrNumOperands;
|
AddrOperands = X86AddrNumOperands;
|
||||||
|
|
||||||
EmitMemModRMByte(MI, CurOp+1, GetX86RegNum(MI.getOperand(CurOp)),
|
if (IsAVXForm)
|
||||||
|
AddrOperands++;
|
||||||
|
|
||||||
|
// Skip the register source (which is encoded in VEX_VVVV)
|
||||||
|
EmitMemModRMByte(MI, IsAVXForm ? CurOp+2 : CurOp+1,
|
||||||
|
GetX86RegNum(MI.getOperand(CurOp)),
|
||||||
TSFlags, CurByte, OS, Fixups);
|
TSFlags, CurByte, OS, Fixups);
|
||||||
CurOp += AddrOperands + 1;
|
CurOp += AddrOperands + 1;
|
||||||
break;
|
break;
|
||||||
|
@ -10084,3 +10084,36 @@ pshufb CPI1_0(%rip), %xmm1
|
|||||||
// CHECK: vdivsd %xmm4, %xmm6, %xmm2
|
// CHECK: vdivsd %xmm4, %xmm6, %xmm2
|
||||||
// CHECK: encoding: [0xc5,0xcb,0x5e,0xd4]
|
// CHECK: encoding: [0xc5,0xcb,0x5e,0xd4]
|
||||||
vdivsd %xmm4, %xmm6, %xmm2
|
vdivsd %xmm4, %xmm6, %xmm2
|
||||||
|
|
||||||
|
// CHECK: vaddss 3735928559(%ebx,%ecx,8), %xmm2, %xmm5
|
||||||
|
// CHECK: encoding: [0xc5,0xea,0x58,0xac,0xcb,0xef,0xbe,0xad,0xde]
|
||||||
|
vaddss 3735928559(%ebx,%ecx,8), %xmm2, %xmm5
|
||||||
|
|
||||||
|
// CHECK: vsubss 3735928559(%ebx,%ecx,8), %xmm2, %xmm5
|
||||||
|
// CHECK: encoding: [0xc5,0xea,0x5c,0xac,0xcb,0xef,0xbe,0xad,0xde]
|
||||||
|
vsubss 3735928559(%ebx,%ecx,8), %xmm2, %xmm5
|
||||||
|
|
||||||
|
// CHECK: vmulss 3735928559(%ebx,%ecx,8), %xmm2, %xmm5
|
||||||
|
// CHECK: encoding: [0xc5,0xea,0x59,0xac,0xcb,0xef,0xbe,0xad,0xde]
|
||||||
|
vmulss 3735928559(%ebx,%ecx,8), %xmm2, %xmm5
|
||||||
|
|
||||||
|
// CHECK: vdivss 3735928559(%ebx,%ecx,8), %xmm2, %xmm5
|
||||||
|
// CHECK: encoding: [0xc5,0xea,0x5e,0xac,0xcb,0xef,0xbe,0xad,0xde]
|
||||||
|
vdivss 3735928559(%ebx,%ecx,8), %xmm2, %xmm5
|
||||||
|
|
||||||
|
// CHECK: vaddsd 3735928559(%ebx,%ecx,8), %xmm2, %xmm5
|
||||||
|
// CHECK: encoding: [0xc5,0xeb,0x58,0xac,0xcb,0xef,0xbe,0xad,0xde]
|
||||||
|
vaddsd 3735928559(%ebx,%ecx,8), %xmm2, %xmm5
|
||||||
|
|
||||||
|
// CHECK: vsubsd 3735928559(%ebx,%ecx,8), %xmm2, %xmm5
|
||||||
|
// CHECK: encoding: [0xc5,0xeb,0x5c,0xac,0xcb,0xef,0xbe,0xad,0xde]
|
||||||
|
vsubsd 3735928559(%ebx,%ecx,8), %xmm2, %xmm5
|
||||||
|
|
||||||
|
// CHECK: vmulsd 3735928559(%ebx,%ecx,8), %xmm2, %xmm5
|
||||||
|
// CHECK: encoding: [0xc5,0xeb,0x59,0xac,0xcb,0xef,0xbe,0xad,0xde]
|
||||||
|
vmulsd 3735928559(%ebx,%ecx,8), %xmm2, %xmm5
|
||||||
|
|
||||||
|
// CHECK: vdivsd 3735928559(%ebx,%ecx,8), %xmm2, %xmm5
|
||||||
|
// CHECK: encoding: [0xc5,0xeb,0x5e,0xac,0xcb,0xef,0xbe,0xad,0xde]
|
||||||
|
vdivsd 3735928559(%ebx,%ecx,8), %xmm2, %xmm5
|
||||||
|
|
||||||
|
@ -135,3 +135,35 @@ vsubsd %xmm8, %xmm9, %xmm10
|
|||||||
// CHECK: vdivsd %xmm8, %xmm9, %xmm10
|
// CHECK: vdivsd %xmm8, %xmm9, %xmm10
|
||||||
// CHECK: encoding: [0xc4,0x41,0x33,0x5e,0xd0]
|
// CHECK: encoding: [0xc4,0x41,0x33,0x5e,0xd0]
|
||||||
vdivsd %xmm8, %xmm9, %xmm10
|
vdivsd %xmm8, %xmm9, %xmm10
|
||||||
|
|
||||||
|
// CHECK: vaddss -4(%rcx,%rbx,8), %xmm10, %xmm11
|
||||||
|
// CHECK: encoding: [0xc5,0x2a,0x58,0x5c,0xd9,0xfc]
|
||||||
|
vaddss -4(%rcx,%rbx,8), %xmm10, %xmm11
|
||||||
|
|
||||||
|
// CHECK: vsubss -4(%rcx,%rbx,8), %xmm10, %xmm11
|
||||||
|
// CHECK: encoding: [0xc5,0x2a,0x5c,0x5c,0xd9,0xfc]
|
||||||
|
vsubss -4(%rcx,%rbx,8), %xmm10, %xmm11
|
||||||
|
|
||||||
|
// CHECK: vmulss -4(%rcx,%rbx,8), %xmm10, %xmm11
|
||||||
|
// CHECK: encoding: [0xc5,0x2a,0x59,0x5c,0xd9,0xfc]
|
||||||
|
vmulss -4(%rcx,%rbx,8), %xmm10, %xmm11
|
||||||
|
|
||||||
|
// CHECK: vdivss -4(%rcx,%rbx,8), %xmm10, %xmm11
|
||||||
|
// CHECK: encoding: [0xc5,0x2a,0x5e,0x5c,0xd9,0xfc]
|
||||||
|
vdivss -4(%rcx,%rbx,8), %xmm10, %xmm11
|
||||||
|
|
||||||
|
// CHECK: vaddsd -4(%rcx,%rbx,8), %xmm10, %xmm11
|
||||||
|
// CHECK: encoding: [0xc5,0x2b,0x58,0x5c,0xd9,0xfc]
|
||||||
|
vaddsd -4(%rcx,%rbx,8), %xmm10, %xmm11
|
||||||
|
|
||||||
|
// CHECK: vsubsd -4(%rcx,%rbx,8), %xmm10, %xmm11
|
||||||
|
// CHECK: encoding: [0xc5,0x2b,0x5c,0x5c,0xd9,0xfc]
|
||||||
|
vsubsd -4(%rcx,%rbx,8), %xmm10, %xmm11
|
||||||
|
|
||||||
|
// CHECK: vmulsd -4(%rcx,%rbx,8), %xmm10, %xmm11
|
||||||
|
// CHECK: encoding: [0xc5,0x2b,0x59,0x5c,0xd9,0xfc]
|
||||||
|
vmulsd -4(%rcx,%rbx,8), %xmm10, %xmm11
|
||||||
|
|
||||||
|
// CHECK: vdivsd -4(%rcx,%rbx,8), %xmm10, %xmm11
|
||||||
|
// CHECK: encoding: [0xc5,0x2b,0x5e,0x5c,0xd9,0xfc]
|
||||||
|
vdivsd -4(%rcx,%rbx,8), %xmm10, %xmm11
|
||||||
|
@ -535,7 +535,8 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
|
|||||||
HANDLE_OPERAND(rmRegister)
|
HANDLE_OPERAND(rmRegister)
|
||||||
|
|
||||||
if (HasVEX_4VPrefix)
|
if (HasVEX_4VPrefix)
|
||||||
// FIXME: encoding of registers in AVX is in 1's complement form.
|
// FIXME: In AVX, the register below becomes the one encoded
|
||||||
|
// in ModRMVEX and the one above the one in the VEX.VVVV field
|
||||||
HANDLE_OPTIONAL(rmRegister)
|
HANDLE_OPTIONAL(rmRegister)
|
||||||
else
|
else
|
||||||
HANDLE_OPTIONAL(immediate)
|
HANDLE_OPTIONAL(immediate)
|
||||||
@ -547,6 +548,12 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
|
|||||||
assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
|
assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
|
||||||
"Unexpected number of operands for MRMSrcMemFrm");
|
"Unexpected number of operands for MRMSrcMemFrm");
|
||||||
HANDLE_OPERAND(roRegister)
|
HANDLE_OPERAND(roRegister)
|
||||||
|
|
||||||
|
if (HasVEX_4VPrefix)
|
||||||
|
// FIXME: In AVX, the register below becomes the one encoded
|
||||||
|
// in ModRMVEX and the one above the one in the VEX.VVVV field
|
||||||
|
HANDLE_OPTIONAL(rmRegister)
|
||||||
|
|
||||||
HANDLE_OPERAND(memory)
|
HANDLE_OPERAND(memory)
|
||||||
HANDLE_OPTIONAL(immediate)
|
HANDLE_OPTIONAL(immediate)
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user