Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 6f9a004

Browse files
committed
Add ARM fconsts/fconstd aliases for vmov.f32/vmov.f64
This commit adds the pre-UAL aliases of fconsts and fconstd for vmov.f32 and vmov.f64. They use an InstAlias rather than a MnemonicAlias to properly support the predicate operand. We need to support encoded 8-bit constants in order to implement the pre-UAL fconsts/fconstd aliases for vmov.f32/vmov.f64, so this commit also fixes parsing of encoded floating point constants used in vmov.f32/vmov.f64 instructions. Now we can support assembly code like this: fconsts s0, #0x70 which is equivalent to vmov.f32 s0, #1.0. Most of the code was already in place to support this feature. Previously the code was trying to accept encoded 8-bit float constants for the vmov.f32/vmov.f64 instructions. It looks like the support for parsing encoded floats was lost in a refactoring in commit r148556 and we did not have any tests in place to catch it. The change in this commit is to keep the parsed value as a 32-bit float instead of a 64-bit double because that is what the isFPImm() function expects to find. There is no loss of precision by using a 32-bit float here because we are still limited to an 8-bit encoded value in the end. Additionally, we explicitly reject encoded 8-bit floats for vmovf.32/64. This is the same as the current behavior, but we now do it explicitly rather than accidently. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198697 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 1485d51 commit 6f9a004

File tree

5 files changed

+110
-7
lines changed

5 files changed

+110
-7
lines changed

lib/Target/ARM/ARMInstrVFP.td

+11
Original file line numberDiff line numberDiff line change
@@ -1762,3 +1762,14 @@ def : VFP2InstAlias<"vmov${p}.f64 $Dn, $Rt, $Rt2",
17621762
// VMOVD does.
17631763
def : VFP2InstAlias<"vmov${p} $Sd, $Sm",
17641764
(VMOVS SPR:$Sd, SPR:$Sm, pred:$p)>;
1765+
1766+
// FCONSTD/FCONSTS alias for vmov.f64/vmov.f32
1767+
// These aliases provide added functionality over vmov.f instructions by
1768+
// allowing users to write assembly containing encoded floating point constants
1769+
// (e.g. #0x70 vs #1.0). Without these alises there is no way for the
1770+
// assembler to accept encoded fp constants (but the equivalent fp-literal is
1771+
// accepted directly by vmovf).
1772+
def : VFP3InstAlias<"fconstd${p} $Dd, $val",
1773+
(FCONSTD DPR:$Dd, vfp_f64imm:$val, pred:$p)>;
1774+
def : VFP3InstAlias<"fconsts${p} $Sd, $val",
1775+
(FCONSTS SPR:$Sd, vfp_f32imm:$val, pred:$p)>;

lib/Target/ARM/AsmParser/ARMAsmParser.cpp

+12-7
Original file line numberDiff line numberDiff line change
@@ -4620,8 +4620,12 @@ parseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
46204620
// for these:
46214621
// vmov.i{8|16|32|64} <dreg|qreg>, #imm
46224622
ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]);
4623-
if (!TyOp->isToken() || (TyOp->getToken() != ".f32" &&
4624-
TyOp->getToken() != ".f64"))
4623+
bool isVmovf = TyOp->isToken() && (TyOp->getToken() == ".f32" ||
4624+
TyOp->getToken() == ".f64");
4625+
ARMOperand *Mnemonic = static_cast<ARMOperand*>(Operands[0]);
4626+
bool isFconst = Mnemonic->isToken() && (Mnemonic->getToken() == "fconstd" ||
4627+
Mnemonic->getToken() == "fconsts");
4628+
if (!(isVmovf || isFconst))
46254629
return MatchOperand_NoMatch;
46264630

46274631
Parser.Lex(); // Eat '#' or '$'.
@@ -4634,7 +4638,7 @@ parseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
46344638
}
46354639
const AsmToken &Tok = Parser.getTok();
46364640
SMLoc Loc = Tok.getLoc();
4637-
if (Tok.is(AsmToken::Real)) {
4641+
if (Tok.is(AsmToken::Real) && isVmovf) {
46384642
APFloat RealVal(APFloat::IEEEsingle, Tok.getString());
46394643
uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
46404644
// If we had a '-' in front, toggle the sign bit.
@@ -4647,15 +4651,16 @@ parseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
46474651
}
46484652
// Also handle plain integers. Instructions which allow floating point
46494653
// immediates also allow a raw encoded 8-bit value.
4650-
if (Tok.is(AsmToken::Integer)) {
4654+
if (Tok.is(AsmToken::Integer) && isFconst) {
46514655
int64_t Val = Tok.getIntVal();
46524656
Parser.Lex(); // Eat the token.
46534657
if (Val > 255 || Val < 0) {
46544658
Error(Loc, "encoded floating point value out of range");
46554659
return MatchOperand_ParseFail;
46564660
}
4657-
double RealVal = ARM_AM::getFPImmFloat(Val);
4658-
Val = APFloat(APFloat::IEEEdouble, RealVal).bitcastToAPInt().getZExtValue();
4661+
float RealVal = ARM_AM::getFPImmFloat(Val);
4662+
Val = APFloat(RealVal).bitcastToAPInt().getZExtValue();
4663+
46594664
Operands.push_back(ARMOperand::CreateImm(
46604665
MCConstantExpr::Create(Val, getContext()), S,
46614666
Parser.getTok().getLoc()));
@@ -4910,7 +4915,7 @@ StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
49104915
Mnemonic == "fmrs" || Mnemonic == "fsqrts" || Mnemonic == "fsubs" ||
49114916
Mnemonic == "fsts" || Mnemonic == "fcpys" || Mnemonic == "fdivs" ||
49124917
Mnemonic == "fmuls" || Mnemonic == "fcmps" || Mnemonic == "fcmpzs" ||
4913-
Mnemonic == "vfms" || Mnemonic == "vfnms" ||
4918+
Mnemonic == "vfms" || Mnemonic == "vfnms" || Mnemonic == "fconsts" ||
49144919
(Mnemonic == "movs" && isThumb()))) {
49154920
Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
49164921
CarrySetting = true;

test/MC/ARM/fconst.s

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
@ RUN: llvm-mc -mcpu=cortex-a8 -triple armv7-apple-darwin -show-encoding < %s | FileCheck %s
2+
3+
@ fconstd/fconsts aliases
4+
fconsts s4, #0x0
5+
fconsts s4, #0x70
6+
fconstd d3, #0x0
7+
fconstd d3, #0x70
8+
9+
fconstsne s5, #0x1
10+
fconstsgt s5, #0x20
11+
fconstdlt d2, #0x3
12+
fconstdge d2, #0x40
13+
14+
@ CHECK: vmov.f32 s4, #2.000000e+00 @ encoding: [0x00,0x2a,0xb0,0xee]
15+
@ CHECK: vmov.f32 s4, #1.000000e+00 @ encoding: [0x00,0x2a,0xb7,0xee]
16+
@ CHECK: vmov.f64 d3, #2.000000e+00 @ encoding: [0x00,0x3b,0xb0,0xee]
17+
@ CHECK: vmov.f64 d3, #1.000000e+00 @ encoding: [0x00,0x3b,0xb7,0xee]
18+
19+
@ CHECK: vmovne.f32 s5, #2.125000e+00 @ encoding: [0x01,0x2a,0xf0,0x1e]
20+
@ CHECK: vmovgt.f32 s5, #8.000000e+00 @ encoding: [0x00,0x2a,0xf2,0xce]
21+
@ CHECK: vmovlt.f64 d2, #2.375000e+00 @ encoding: [0x03,0x2b,0xb0,0xbe]
22+
@ CHECK: vmovge.f64 d2, #1.250000e-01 @ encoding: [0x00,0x2b,0xb4,0xae]

test/MC/ARM/fp-const-errors.s

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
@ RUN: not llvm-mc -mcpu=cortex-a8 -triple armv7-none-linux-gnueabi < %s 2>&1 | FileCheck %s
2+
3+
@ Test for floating point constants that are out of the 8-bit encoded value range
4+
vmov.f32 s2, #32.0
5+
@ CHECK: error: invalid operand for instruction
6+
7+
vmov.f64 d2, #32.0
8+
@ CHECK: error: invalid operand for instruction
9+
10+
@ Test that vmov.f instructions do not accept an 8-bit encoded float as an operand
11+
vmov.f32 s1, #0x70
12+
@ CHECK: error: invalid floating point immediate
13+
14+
vmov.f64 d2, #0x70
15+
@ CHECK: error: invalid floating point immediate
16+
17+
@ Test that fconst instructions do not accept a float constant as an operand
18+
fconsts s1, #1.0
19+
@ CHECK: error: invalid floating point immediate
20+
21+
fconstd d2, #1.0
22+
@ CHECK: error: invalid floating point immediate

test/MC/ARM/simple-fp-encoding.s

+43
Original file line numberDiff line numberDiff line change
@@ -395,3 +395,46 @@
395395

396396
@ CHECK: vmov.i32 d4, #0x0 @ encoding: [0x10,0x40,0x80,0xf2]
397397
@ CHECK: vmov.i32 d4, #0x42000000 @ encoding: [0x12,0x46,0x84,0xf2]
398+
399+
@ Test encoding of floating point constants for vmov functions
400+
@ vfp3
401+
vmov.f32 s5, #1.0
402+
vmov.f32 s5, #0.125
403+
vmov.f32 s5, #-1.875
404+
vmov.f32 s5, #-0.59375
405+
406+
vmov.f64 d6, #1.0
407+
vmov.f64 d6, #0.125
408+
vmov.f64 d6, #-1.875
409+
vmov.f64 d6, #-0.59375
410+
411+
@ neon
412+
vmov.f32 d7, #1.0
413+
vmov.f32 d7, #0.125
414+
vmov.f32 d7, #-1.875
415+
vmov.f32 d7, #-0.59375
416+
417+
vmov.f32 q8, #1.0
418+
vmov.f32 q8, #0.125
419+
vmov.f32 q8, #-1.875
420+
vmov.f32 q8, #-0.59375
421+
422+
@ CHECK: vmov.f32 s5, #1.000000e+00 @ encoding: [0x00,0x2a,0xf7,0xee]
423+
@ CHECK: vmov.f32 s5, #1.250000e-01 @ encoding: [0x00,0x2a,0xf4,0xee]
424+
@ CHECK: vmov.f32 s5, #-1.875000e+00 @ encoding: [0x0e,0x2a,0xff,0xee]
425+
@ CHECK: vmov.f32 s5, #-5.937500e-01 @ encoding: [0x03,0x2a,0xfe,0xee]
426+
427+
@ CHECK: vmov.f64 d6, #1.000000e+00 @ encoding: [0x00,0x6b,0xb7,0xee]
428+
@ CHECK: vmov.f64 d6, #1.250000e-01 @ encoding: [0x00,0x6b,0xb4,0xee]
429+
@ CHECK: vmov.f64 d6, #-1.875000e+00 @ encoding: [0x0e,0x6b,0xbf,0xee]
430+
@ CHECK: vmov.f64 d6, #-5.937500e-01 @ encoding: [0x03,0x6b,0xbe,0xee]
431+
432+
@ CHECK: vmov.f32 d7, #1.000000e+00 @ encoding: [0x10,0x7f,0x87,0xf2]
433+
@ CHECK: vmov.f32 d7, #1.250000e-01 @ encoding: [0x10,0x7f,0x84,0xf2]
434+
@ CHECK: vmov.f32 d7, #-1.875000e+00 @ encoding: [0x1e,0x7f,0x87,0xf3]
435+
@ CHECK: vmov.f32 d7, #-5.937500e-01 @ encoding: [0x13,0x7f,0x86,0xf3]
436+
437+
@ CHECK: vmov.f32 q8, #1.000000e+00 @ encoding: [0x50,0x0f,0xc7,0xf2]
438+
@ CHECK: vmov.f32 q8, #1.250000e-01 @ encoding: [0x50,0x0f,0xc4,0xf2]
439+
@ CHECK: vmov.f32 q8, #-1.875000e+00 @ encoding: [0x5e,0x0f,0xc7,0xf3]
440+
@ CHECK: vmov.f32 q8, #-5.937500e-01 @ encoding: [0x53,0x0f,0xc6,0xf3]

0 commit comments

Comments
 (0)