Commit 341158aa by Karl Schimpf

Add VMUL vector instructions to the integrated ARM assembler.

parent 625dfb38
......@@ -1278,17 +1278,18 @@ void Assembler::vsubqs(QRegister qd, QRegister qn, QRegister qm) {
EmitSIMDqqq(B21 | B11 | B10 | B8, kSWord, qd, qn, qm);
}
#if 0
// Moved to ARM32::AssemblerARM32::vmulqi().
void Assembler::vmulqi(OperandSize sz,
QRegister qd, QRegister qn, QRegister qm) {
EmitSIMDqqq(B11 | B8 | B4, sz, qd, qn, qm);
}
// Moved to ARM32::AssemblerARM32::vmulqf().
void Assembler::vmulqs(QRegister qd, QRegister qn, QRegister qm) {
EmitSIMDqqq(B24 | B11 | B10 | B8 | B4, kSWord, qd, qn, qm);
}
#endif
void Assembler::vshlqi(OperandSize sz,
QRegister qd, QRegister qm, QRegister qn) {
......
......@@ -690,9 +690,11 @@ class Assembler : public ValueObject {
void vmuls(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
// Moved to Arm32::AssemblerARM32::vmuld()
void vmuld(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
#endif
// Moved to ARM32::AssemblerARM32::vmulqi().
void vmulqi(OperandSize sz, QRegister qd, QRegister qn, QRegister qm);
// Moved to ARM32::AssemblerARM32::vmulqf().
void vmulqs(QRegister qd, QRegister qn, QRegister qm);
#endif
void vshlqi(OperandSize sz, QRegister qd, QRegister qm, QRegister qn);
void vshlqu(OperandSize sz, QRegister qd, QRegister qm, QRegister qn);
#if 0
......
......@@ -2757,6 +2757,30 @@ void AssemblerARM32::vmuld(const Operand *OpDd, const Operand *OpDn,
emitVFPddd(Cond, VmuldOpcode, OpDd, OpDn, OpDm, Vmuld);
}
void AssemblerARM32::vmulqi(Type ElmtTy, const Operand *OpQd,
const Operand *OpQn, const Operand *OpQm) {
// VMUL, VMULL (integer and polynomial) - ARM section A8.8.350, encoding A1:
// vmul<c>.<dt> <Qd>, <Qn>, <Qm>
//
// 111100100Dssnnn0ddd01001NqM1mmm0 where Dddd=Qd, Nnnn=Qn, Mmmm=Qm, and
// dt in [i8, i16, i32] where ss is the index.
assert(ElmtTy != IceType_i64 && "vmulqi on i64 vector not allowed");
constexpr const char *Vmulqi = "vmulqi";
constexpr IValueT VmulqiOpcode = B11 | B8 | B4;
emitSIMDqqq(VmulqiOpcode, ElmtTy, OpQd, OpQn, OpQm, Vmulqi);
}
void AssemblerARM32::vmulqf(const Operand *OpQd, const Operand *OpQn,
const Operand *OpQm) {
// VMUL (floating-point) - ARM section A8.8.351, encoding A1:
// vmul.f32 <Qd>, <Qn>, <Qm>
//
// 111100110D00nnn0ddd01101MqM1mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
constexpr const char *Vmulqf = "vmulqf";
constexpr IValueT VmulqfOpcode = B24 | B11 | B10 | B8 | B4;
emitSIMDqqq(VmulqfOpcode, IceType_f32, OpQd, OpQn, OpQm, Vmulqf);
}
void AssemblerARM32::vorrq(const Operand *OpQd, const Operand *OpQm,
const Operand *OpQn) {
// VORR (register) - ARM section A8.8.360, encoding A1:
......
......@@ -435,6 +435,13 @@ public:
void vmuld(const Operand *OpDd, const Operand *OpDn, const Operand *OpDm,
CondARM32::Cond Cond);
// Integer vector multiply.
void vmulqi(Type ElmtTy, const Operand *OpQd, const Operand *OpQn,
const Operand *OpQm);
// Float vector multiply.
void vmulqf(const Operand *OpQd, const Operand *OpQn, const Operand *OpQm);
void vmuls(const Operand *OpSd, const Operand *OpSn, const Operand *OpSm,
CondARM32::Cond Cond);
......
......@@ -621,7 +621,6 @@ template <> void InstARM32Vadd::emitIAS(const Cfg *Func) const {
default:
llvm::report_fatal_error("Vadd not defined on type " +
typeIceString(DestTy));
break;
case IceType_v16i8:
case IceType_v8i16:
case IceType_v4i32:
......@@ -778,20 +777,28 @@ template <> void InstARM32Vsub::emitIAS(const Cfg *Func) const {
template <> void InstARM32Vmul::emitIAS(const Cfg *Func) const {
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
const Variable *Dest = getDest();
switch (Dest->getType()) {
const Type DestTy = Dest->getType();
switch (DestTy) {
default:
// TODO(kschimpf) Figure if more cases are needed.
emitUsingTextFixup(Func);
return;
llvm::report_fatal_error("Vmul not defined on type " +
typeIceString(DestTy));
case IceType_v16i8:
case IceType_v8i16:
case IceType_v4i32:
Asm->vmulqi(typeElementType(DestTy), Dest, getSrc(0), getSrc(1));
break;
case IceType_v4f32:
Asm->vmulqf(Dest, getSrc(0), getSrc(1));
break;
case IceType_f32:
Asm->vmuls(getDest(), getSrc(0), getSrc(1), CondARM32::AL);
assert(!Asm->needsTextFixup());
return;
Asm->vmuls(Dest, getSrc(0), getSrc(1), CondARM32::AL);
break;
case IceType_f64:
Asm->vmuld(getDest(), getSrc(0), getSrc(1), CondARM32::AL);
assert(!Asm->needsTextFixup());
return;
Asm->vmuld(Dest, getSrc(0), getSrc(1), CondARM32::AL);
break;
}
assert(!Asm->needsTextFixup());
}
InstARM32Call::InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget)
......
......@@ -34,7 +34,7 @@ entry:
; ASM: vmul.f32 q10, q10, q11
; DIS: 8: f3444df6
; IASM: vmul.f32
; IASM-NOT: vmul.f32
ret <4 x float> %res
}
......@@ -49,7 +49,7 @@ entry:
; ASM: vmul.i32 q10, q10, q11
; DIS: 28: f26449f6
; IASM: vmul.i32
; IASM-NOT: vmul.i32
ret <4 x i32> %res
}
......@@ -64,7 +64,7 @@ entry:
; ASM: vmul.i16 q10, q10, q11
; DIS: 48: f25449f6
; IASM: vmul.i16
; IASM-NOT: vmul.i16
ret <8 x i16> %res
}
......@@ -79,7 +79,7 @@ entry:
; ASM: vmul.i8 q10, q10, q11
; DIS: 68: f24449f6
; IASM: vmul.i8
; IASM-NOT: vmul.i8
ret <16 x i8> %res
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment