Commit 266c5a25 by Karl Schimpf

Add VSQRT instruction to the integrated ARM assembler.

Also fixes the non-hybrid ARM assembler to display the instruction it can't translate, making it easier to see what can't be handled. This change was added to see what still isn't being translated in spec2k performance tests. BUG= https://bugs.chromium.org/p/nativeclient/issues/detail?id=4334 R=jpp@chromium.org Review URL: https://codereview.chromium.org/1647113003 .
parent a880ac8f
......@@ -1057,16 +1057,17 @@ void Assembler::vnegd(DRegister dd, DRegister dm, Condition cond) {
EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm);
}
#if 0
// Moved to ARM32::AssemblerARM32::vsqrts().
void Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) {
EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm);
}
// Moved to ARM32::AssemblerARM32::vsqrtd().
void Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) {
EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm);
}
#if 0
// Moved to ARM32::AssemblerARM32::emitVFPsd
void Assembler::EmitVFPsd(Condition cond, int32_t opcode,
SRegister sd, DRegister dm) {
......
......@@ -737,10 +737,12 @@ class Assembler : public ValueObject {
void vnegs(SRegister sd, SRegister sm, Condition cond = AL);
void vnegd(DRegister dd, DRegister dm, Condition cond = AL);
void vnegqs(QRegister qd, QRegister qm);
#if 0
// Moved to ARM32::AssemblerARM32::vsqrts().
void vsqrts(SRegister sd, SRegister sm, Condition cond = AL);
// Moved to ARM32::AssemblerARM32::vsqrts().
void vsqrtd(DRegister dd, DRegister dm, Condition cond = AL);
#if 0
// Moved to ARM32::AssemblerARM32::vcvtsd().
void vcvtsd(SRegister sd, DRegister dm, Condition cond = AL);
// Moved to ARM32::AssemblerARM32:vcvtds().
......
......@@ -2744,5 +2744,33 @@ void AssemblerARM32::vpush(const Variable *OpBaseReg, SizeT NumConsecRegs,
emitVStackOp(Cond, VpushOpcode, OpBaseReg, NumConsecRegs);
}
void AssemblerARM32::vsqrtd(const Operand *OpDd, const Operand *OpDm,
CondARM32::Cond Cond) {
// VSQRT - ARM section A8.8.401, encoding A1:
// vsqrt<c>.f64 <Dd>, <Dm>
//
// cccc11101D110001dddd101111M0mmmm where cccc=Cond, Ddddd=Sd, and Mmmmm=Sm.
constexpr const char *Vsqrtd = "vsqrtd";
IValueT Dd = encodeDRegister(OpDd, "Dd", Vsqrtd);
IValueT Dm = encodeDRegister(OpDm, "Dm", Vsqrtd);
constexpr IValueT VsqrtdOpcode = B23 | B21 | B20 | B16 | B7 | B6;
constexpr IValueT D0 = 0;
emitVFPddd(Cond, VsqrtdOpcode, Dd, D0, Dm);
}
void AssemblerARM32::vsqrts(const Operand *OpSd, const Operand *OpSm,
CondARM32::Cond Cond) {
// VSQRT - ARM section A8.8.401, encoding A1:
// vsqrt<c>.f32 <Sd>, <Sm>
//
// cccc11101D110001dddd101011M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
constexpr const char *Vsqrts = "vsqrts";
IValueT Sd = encodeSRegister(OpSd, "Sd", Vsqrts);
IValueT Sm = encodeSRegister(OpSm, "Sm", Vsqrts);
constexpr IValueT VsqrtsOpcode = B23 | B21 | B20 | B16 | B7 | B6;
constexpr IValueT S0 = 0;
emitVFPsss(Cond, VsqrtsOpcode, Sd, S0, Sm);
}
} // end of namespace ARM32
} // end of namespace Ice
......@@ -429,6 +429,10 @@ public:
void vpush(const Variable *OpBaseReg, SizeT NumConsecRegs,
CondARM32::Cond Cond);
void vsqrtd(const Operand *OpDd, const Operand *OpDm, CondARM32::Cond Cond);
void vsqrts(const Operand *OpSd, const Operand *OpSm, CondARM32::Cond Cond);
void vstrd(const Operand *OpDd, const Operand *OpAddress,
CondARM32::Cond Cond, const TargetInfo &TInfo);
......
......@@ -97,10 +97,6 @@ void InstARM32::emitUsingTextFixup(const Cfg *Func) const {
if (!BuildDefs::dump())
return;
GlobalContext *Ctx = Func->getContext();
if (Ctx->getFlags().getDisableHybridAssembly()) {
UnimplementedError(Ctx->getFlags());
return;
}
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
std::string Buffer;
llvm::raw_string_ostream StrBuf(Buffer);
......@@ -113,6 +109,11 @@ void InstARM32::emitUsingTextFixup(const Cfg *Func) const {
Asm->incEmitTextSize(InstSize);
emit(Func);
Ctx->setStrEmit(OldStr);
if (Ctx->getFlags().getDisableHybridAssembly()) {
llvm::errs() << "Can't assemble: " << StrBuf.str() << "\n";
UnimplementedError(Ctx->getFlags());
return;
}
Asm->emitTextInst(StrBuf.str(), Asm->getEmitTextSize());
}
......@@ -1683,6 +1684,29 @@ template <> void InstARM32Uxt::emitIAS(const Cfg *Func) const {
emitUsingTextFixup(Func);
}
template <InstARM32::InstKindARM32 K>
void InstARM32UnaryopFP<K>::emitIAS(const Cfg *Func) const {
emitUsingTextFixup(Func);
}
template <> void InstARM32Vsqrt::emitIAS(const Cfg *Func) const {
assert(getSrcSize() == 1);
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
const Operand *Dest = getDest();
switch (Dest->getType()) {
case IceType_f32:
Asm->vsqrts(Dest, getSrc(0), getPredicate());
break;
case IceType_f64:
Asm->vsqrtd(Dest, getSrc(0), getPredicate());
break;
default:
llvm::report_fatal_error("Vqrt of non-floating type");
}
if (Asm->needsTextFixup())
emitUsingTextFixup(Func);
}
const char *InstARM32Pop::getGPROpcode() const { return "pop"; }
const char *InstARM32Pop::getSRegOpcode() const { return "vpop"; }
......
......@@ -571,6 +571,7 @@ public:
return;
emitUnaryopFP(Opcode, this, Func);
}
void emitIAS(const Cfg *Func) const override;
void dump(const Cfg *Func) const override {
if (!BuildDefs::dump())
return;
......
; Show that we can translate intrinsic vsqrt into a binary instruction.
; REQUIRES: allow_dump
; Compile using standalone assembler.
; RUN: %p2i --filetype=asm -i %s --target=arm32 --args -Om1 -allow-extern \
; RUN: -reg-use s20,d20 | FileCheck %s --check-prefix=ASM
; Show bytes in assembled standalone code.
; RUN: %p2i --filetype=asm -i %s --target=arm32 --assemble --disassemble \
; RUN: --args -Om1 -allow-extern -reg-use s20,d20 \
; RUN: | FileCheck %s --check-prefix=DIS
; Compile using integrated assembler.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -Om1 -allow-extern \
; RUN: -reg-use s20,d20 | FileCheck %s --check-prefix=IASM
; Show bytes in assembled integrated code.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --assemble --disassemble \
; RUN: --args -Om1 -allow-extern -reg-use s20,d20 \
; RUN: | FileCheck %s --check-prefix=DIS
declare float @llvm.sqrt.f32(float)
declare double @llvm.sqrt.f64(double)
define internal float @sqrtFloat() {
; ASM-LABEL: sqrtFloat:
; DIS-LABEL: 00000000 <sqrtFloat>:
; IASM-LABEL: sqrtFloat:
%v = call float @llvm.sqrt.f32(float 0.5);
; ASM: vsqrt.f32 s20, s20
; DIS: c: eeb1aaca
; IASM-NOT: vsqrt.f32
ret float %v
}
define internal double @sqrtDouble() {
; ASM-LABEL: sqrtDouble:
; DIS-LABEL: 00000030 <sqrtDouble>:
; IASM-LABEL: sqrtDouble:
%v = call double @llvm.sqrt.f64(double 0.5);
; ASM: vsqrt.f64 d20, d20
; DIS: 38: eef14be4
; IASM-NOT: vsqrt.f64
ret double %v
}
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