Commit 50cfcb06 by Karl Schimpf

Add VSUB vector instruction to the integrated ARM assembler.

parent 82975ba6
......@@ -682,10 +682,10 @@ class Assembler : public ValueObject {
void vsubs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
// Moved to Arm32::AssemblerARM32::vsubd()
void vsubd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
#endif
// Moved to ARM32::AssemblerARM32::vsubqi().
void vsubqi(OperandSize sz, QRegister qd, QRegister qn, QRegister qm);
// Moved to ARM32::AssemblerARM32::vsubqf().
void vsubqs(QRegister qd, QRegister qn, QRegister qm);
#if 0
// Moved to Arm32::AssemblerARM32::vmuls()
void vmuls(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
// Moved to Arm32::AssemblerARM32::vmuld()
......
......@@ -2158,7 +2158,7 @@ void AssemblerARM32::vaddqi(Type ElmtTy, const Operand *OpQd,
// VADD (integer) - ARM section A8.8.282, encoding A1:
// vadd.<dt> <Qd>, <Qn>, <Qm>
//
// 111100100Dssnnn0ddd01000NqM0mmm0 where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm,
// 111100100Dssnnn0ddd01000N1M0mmm0 where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm,
// and dt in [i8, i16, i32, i64] where ss is the index.
constexpr const char *Vaddqi = "vaddqi";
constexpr IValueT VaddqiOpcode = B11;
......@@ -2777,6 +2777,29 @@ void AssemblerARM32::vsubd(const Operand *OpDd, const Operand *OpDn,
emitVFPddd(Cond, VsubdOpcode, OpDd, OpDn, OpDm, Vsubd);
}
void AssemblerARM32::vsubqi(Type ElmtTy, const Operand *OpQd,
const Operand *OpQm, const Operand *OpQn) {
// VSUB (integer) - ARM section A8.8.414, encoding A1:
// vsub.<dt> <Qd>, <Qn>, <Qm>
//
// 111100110Dssnnn0ddd01000N1M0mmm0 where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm,
// and dt in [i8, i16, i32, i64] where ss is the index.
constexpr const char *Vsubqi = "vsubqi";
constexpr IValueT VsubqiOpcode = B24 | B11;
emitSIMDqqq(VsubqiOpcode, ElmtTy, OpQd, OpQm, OpQn, Vsubqi);
}
void AssemblerARM32::vsubqf(const Operand *OpQd, const Operand *OpQn,
const Operand *OpQm) {
// VSUB (floating-point) - ARM section A8.8.415, Encoding A1:
// vsub.f32 <Qd>, <Qn>, <Qm>
//
// 111100100D10nnn0ddd01101N1M0mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
constexpr const char *Vsubqf = "vsubqf";
constexpr IValueT VsubqfOpcode = B21 | B11 | B10 | B8;
emitSIMDqqq(VsubqfOpcode, IceType_f32, OpQd, OpQn, OpQm, Vsubqf);
}
void AssemblerARM32::emitVStackOp(CondARM32::Cond Cond, IValueT Opcode,
const Variable *OpBaseReg,
SizeT NumConsecRegs) {
......
......@@ -461,6 +461,13 @@ public:
void vsubd(const Operand *OpDd, const Operand *OpDn, const Operand *OpDm,
CondARM32::Cond Cond);
// Integer vector subtract.
void vsubqi(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
const Operand *OpQn);
// Float vector subtract
void vsubqf(const Operand *OpQd, const Operand *OpQm, const Operand *OpQn);
void vsubs(const Operand *OpSd, const Operand *OpSn, const Operand *OpSm,
CondARM32::Cond Cond);
......
......@@ -735,20 +735,37 @@ template <> void InstARM32Vorr::emitIAS(const Cfg *Func) const {
template <> void InstARM32Vsub::emitIAS(const Cfg *Func) const {
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
const Variable *Dest = getDest();
switch (Dest->getType()) {
default:
// TODO(kschimpf) Figure if more cases are needed.
emitUsingTextFixup(Func);
Type DestTy = Dest->getType();
switch (DestTy) {
case IceType_void:
case IceType_i1:
case IceType_i8:
case IceType_i16:
case IceType_i32:
case IceType_i64:
case IceType_v4i1:
case IceType_v8i1:
case IceType_v16i1:
case IceType_NUM:
llvm::report_fatal_error("Vsub not defined on type " +
std::string(typeString(DestTy)));
break;
case IceType_v16i8:
case IceType_v8i16:
case IceType_v4i32:
Asm->vsubqi(typeElementType(DestTy), Dest, getSrc(0), getSrc(1));
break;
case IceType_v4f32:
Asm->vsubqf(Dest, getSrc(0), getSrc(1));
break;
case IceType_f32:
Asm->vsubs(getDest(), getSrc(0), getSrc(1), CondARM32::AL);
assert(!Asm->needsTextFixup());
break;
case IceType_f64:
Asm->vsubd(getDest(), getSrc(0), getSrc(1), CondARM32::AL);
assert(!Asm->needsTextFixup());
break;
}
assert(!Asm->needsTextFixup());
}
template <> void InstARM32Vmul::emitIAS(const Cfg *Func) const {
......
......@@ -34,7 +34,7 @@ entry:
; ASM: vsub.f32 q10, q10, q11
; DIS: 8: f2644de6
; IASM: vsub.f32
; IASM-NOT: vsub.f32
ret <4 x float> %res
}
......@@ -49,7 +49,7 @@ entry:
; ASM: vsub.i32 q10, q10, q11
; DIS: 28: f36448e6
; IASM: vsub.i32
; IASM-NOT: vsub.i32
ret <4 x i32> %res
}
......@@ -64,7 +64,7 @@ entry:
; ASM: vsub.i16 q10, q10, q11
; DIS: 48: f35448e6
; IASM: vsub.i16
; IASM-NOT: vsub.i16
ret <8 x i16> %res
}
......@@ -79,7 +79,7 @@ entry:
; ASM: vsub.i8 q10, q10, q11
; DIS: 68: f34448e6
; IASM: vsub.i8
; IASM-NOT: vsub.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