Commit ee718275 by Karl Schimpf

Add the VMRS instruction to the integrated ARM assembler.

Note: Only adds the APSR_nzcv register form of the instruction. BUG= https://bugs.chromium.org/p/nativeclient/issues/detail?id=4334 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1636473002 .
parent 399c2bdd
......@@ -1171,8 +1171,8 @@ void Assembler::vcmpsz(SRegister sd, Condition cond) {
void Assembler::vcmpdz(DRegister dd, Condition cond) {
EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0);
}
#endif
// APSR_nzcv version moved to ARM32::AssemblerARM32::vmrsAPSR_nzcv()
void Assembler::vmrs(Register rd, Condition cond) {
ASSERT(TargetCPUFeatures::vfp_supported());
ASSERT(cond != kNoCondition);
......@@ -1182,7 +1182,7 @@ void Assembler::vmrs(Register rd, Condition cond) {
B11 | B9 | B4;
Emit(encoding);
}
#endif
void Assembler::vmstat(Condition cond) {
vmrs(APSR, cond);
......
......@@ -755,9 +755,10 @@ class Assembler : public ValueObject {
void vcmpsz(SRegister sd, Condition cond = AL);
// Moved to ARM23::AssemblerARM32::vcmpdz().
void vcmpdz(DRegister dd, Condition cond = AL);
#endif
// APSR_nzcv version moved to ARM32::AssemblerARM32::vmrsAPSR_nzcv()
void vmrs(Register rd, Condition cond = AL);
#endif
void vmstat(Condition cond = AL);
// Duplicates the operand of size sz at index idx from dm to all elements of
......
......@@ -2382,7 +2382,7 @@ void AssemblerARM32::vldrs(const Operand *OpSd, const Operand *OpAddress,
void AssemblerARM32::vmovsr(const Operand *OpSn, const Operand *OpRt,
CondARM32::Cond Cond) {
// VMOV (between ARM core register and single-precision register)
// ARM seciont A8.8.343, encoding A1.
// ARM section A8.8.343, encoding A1.
//
// vmov<c> <Sn>, <Rt>
//
......@@ -2400,6 +2400,20 @@ void AssemblerARM32::vmovsr(const Operand *OpSn, const Operand *OpRt,
emitInst(Encoding);
}
void AssemblerARM32::vmrsAPSR_nzcv(CondARM32::Cond Cond) {
// MVRS - ARM section A*.8.348, encoding A1:
// vmrs<c> APSR_nzcv, FPSCR
//
// cccc111011110001tttt101000010000 where tttt=0x15 (i.e. when Rt=pc, use
// APSR_nzcv instead).
assert(CondARM32::isDefined(Cond));
IValueT Encoding = B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 | B15 | B14 |
B13 | B12 | B11 | B9 | B4 |
(encodeCondition(Cond) << kConditionShift);
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
emitInst(Encoding);
}
void AssemblerARM32::vmuls(const Operand *OpSd, const Operand *OpSn,
const Operand *OpSm, CondARM32::Cond Cond) {
// VMUL (floating-point) - ARM section A8.8.351, encoding A2:
......
......@@ -384,6 +384,9 @@ public:
void vmovsr(const Operand *OpSn, const Operand *OpRt, CondARM32::Cond Cond);
// Uses APSR_nzcv as register
void vmrsAPSR_nzcv(CondARM32::Cond Cond);
void vmuld(const Operand *OpDd, const Operand *OpDn, const Operand *OpDm,
CondARM32::Cond Cond);
......
......@@ -1998,6 +1998,12 @@ void InstARM32Vmrs::emit(const Cfg *Func) const {
"FPSCR";
}
void InstARM32Vmrs::emitIAS(const Cfg *Func) const {
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->vmrsAPSR_nzcv(getPredicate());
assert(!Asm->needsTextFixup());
}
void InstARM32Vmrs::dump(const Cfg *Func) const {
if (!BuildDefs::dump())
return;
......
......@@ -1383,6 +1383,7 @@ public:
return new (Func->allocate<InstARM32Vmrs>()) InstARM32Vmrs(Func, Predicate);
}
void emit(const Cfg *Func) const override;
void emitIAS(const Cfg *Func) const override;
void dump(const Cfg *Func) const override;
static bool classof(const Inst *Inst) { return isClassof(Inst, Vmrs); }
......
; Test the "vmrs APSR_nzcv, FPSCR" form of the VMRS instruction.
; REQUIRES: allow_dump
; Compile using standalone assembler.
; RUN: %p2i --filetype=asm -i %s --target=arm32 --args -Om1 \
; RUN: | FileCheck %s --check-prefix=ASM
; Show bytes in assembled standalone code.
; RUN: %p2i --filetype=asm -i %s --target=arm32 --assemble --disassemble \
; RUN: --args -Om1 \
; RUN: | FileCheck %s --check-prefix=DIS
; Compile using integrated assembler.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -Om1 \
; RUN: | FileCheck %s --check-prefix=IASM
; Show bytes in assembled integrated code.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --assemble --disassemble \
; RUN: --args -Om1 \
; RUN: | FileCheck %s --check-prefix=DIS
define internal i32 @testVmrsASPR_nzcv() {
; ASM-LABEL: testVmrsASPR_nzcv:
; DIS-LABEL: 00000000 <testVmrsASPR_nzcv>:
entry:
; ASM: .LtestVmrsASPR_nzcv$entry:
%test = fcmp olt float 0.0, 0.0
; ASM: vmrs APSR_nzcv, FPSCR
; DIS: 18: eef1fa10
; IASM-NOT: vmrs
%result = zext i1 %test to i32
ret i32 %result
}
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