Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Unified Diff: src/IceAssemblerARM32.cpp

Issue 1540653003: Add VADD instruction to the ARM integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits and show extracted DART code. Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/IceAssemblerARM32.cpp
diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp
index 1ad1efad2cdb1e3bcf35155793a61b79af8dfaea..1fdcfe4098c3d11c5ea7da76023e0f8276a9ba2c 100644
--- a/src/IceAssemblerARM32.cpp
+++ b/src/IceAssemblerARM32.cpp
@@ -140,9 +140,11 @@ RegARM32::GPRRegister decodeGPRRegister(IValueT R) {
return static_cast<RegARM32::GPRRegister>(R);
}
-bool isGPRRegisterDefined(IValueT R) {
- return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR);
-}
+bool isGPRRegisterDefined(IValueT R) { return R <= RegARM32::getNumGPRRegs(); }
Jim Stichnoth 2015/12/19 15:31:25 This "<=" looked like a bug to me, until I looked
Karl 2016/01/05 20:24:31 The problem here is that R is the assembler encode
+
+bool isSRegisterDefined(IValueT S) { return S <= RegARM32::getNumSRegs(); }
+
+bool isDRegisterDefined(IValueT D) { return D <= RegARM32::getNumDRegs(); }
bool isConditionDefined(CondARM32::Cond Cond) {
return Cond != CondARM32::kNone;
@@ -208,6 +210,20 @@ IValueT getEncodedSRegNum(const Variable *Var) {
return RegARM32::getEncodedSReg(Var->getRegNum());
}
+IValueT getEncodedDRegNum(const Variable *Var) {
+ assert(Var->hasReg());
+ assert(RegARM32::isEncodedDReg(Var->getRegNum()));
+ return RegARM32::getEncodedDReg(Var->getRegNum());
+}
+
+IValueT getYInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY & 0x1; }
+
+IValueT getXXXXInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY >> 1; }
+
+IValueT getYInRegYXXXX(IValueT RegYXXXX) { return RegYXXXX >> 4; }
+
+IValueT getXXXXInRegYXXXX(IValueT RegYXXXX) { return RegYXXXX & 0x0f; }
+
// The way an operand is encoded into a sequence of bits in functions
// encodeOperand and encodeAddress below.
enum EncodedOperand {
@@ -278,11 +294,26 @@ IValueT encodeShiftRotateReg(IValueT Rm, OperandARM32::ShiftKind Shift,
(Rm << kRmShift);
}
-EncodedOperand encodeOperand(const Operand *Opnd, IValueT &Value) {
+// Defines the set of registers expected in an operand.
+enum RegSetWanted { WantGPRegs, WantSRegs, WantDRegs };
+
+EncodedOperand encodeOperand(const Operand *Opnd, IValueT &Value,
+ RegSetWanted WantedRegSet) {
+ (void)WantedRegSet;
Value = 0; // Make sure initialized.
if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
if (Var->hasReg()) {
- Value = getEncodedGPRegNum(Var);
+ switch (WantedRegSet) {
+ case WantGPRegs:
+ Value = getEncodedGPRegNum(Var);
+ break;
+ case WantSRegs:
+ Value = getEncodedSRegNum(Var);
+ break;
+ case WantDRegs:
+ Value = getEncodedDRegNum(Var);
+ break;
+ }
return EncodedAsRegister;
}
return CantEncode;
@@ -302,11 +333,11 @@ EncodedOperand encodeOperand(const Operand *Opnd, IValueT &Value) {
if (const auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Opnd)) {
Operand *Amt = FlexReg->getShiftAmt();
IValueT Rm;
- if (encodeOperand(FlexReg->getReg(), Rm) != EncodedAsRegister)
+ if (encodeOperand(FlexReg->getReg(), Rm, WantGPRegs) != EncodedAsRegister)
return CantEncode;
if (const auto *Var = llvm::dyn_cast<Variable>(Amt)) {
IValueT Rs;
- if (encodeOperand(Var, Rs) != EncodedAsRegister)
+ if (encodeOperand(Var, Rs, WantGPRegs) != EncodedAsRegister)
return CantEncode;
Value = encodeShiftRotateReg(Rm, FlexReg->getShiftOp(), Rs);
return EncodedAsRegShiftReg;
@@ -421,22 +452,52 @@ bool canEncodeBranchOffset(IOffsetT Offset) {
Utils::IsInt(kBranchOffsetBits, Offset >> 2);
}
-IValueT encodeRegister(const Operand *OpReg, const char *RegName,
- const char *InstName) {
+IValueT encodeRegister(const Operand *OpReg, RegSetWanted WantedRegSet,
+ const char *RegName, const char *InstName) {
IValueT Reg = 0;
- if (encodeOperand(OpReg, Reg) != EncodedAsRegister)
+ if (encodeOperand(OpReg, Reg, WantedRegSet) != EncodedAsRegister)
llvm::report_fatal_error(std::string(InstName) + ": Can't find register " +
RegName);
return Reg;
}
-void verifyRegDefined(IValueT Reg, const char *RegName, const char *InstName) {
+IValueT encodeGPRegister(const Operand *OpReg, const char *RegName,
+ const char *InstName) {
+ return encodeRegister(OpReg, WantGPRegs, RegName, InstName);
+}
+
+IValueT encodeSRegister(const Operand *OpReg, const char *RegName,
+ const char *InstName) {
+ return encodeRegister(OpReg, WantSRegs, RegName, InstName);
+}
+
+IValueT encodeDRegister(const Operand *OpReg, const char *RegName,
+ const char *InstName) {
+ return encodeRegister(OpReg, WantDRegs, RegName, InstName);
+}
+
+void verifyGPRegDefined(IValueT Reg, const char *RegName,
+ const char *InstName) {
if (BuildDefs::minimal())
return;
if (!isGPRRegisterDefined(Reg))
llvm::report_fatal_error(std::string(InstName) + ": Can't find " + RegName);
}
+void verifySRegDefined(IValueT Reg, const char *RegName, const char *InstName) {
+ if (BuildDefs::minimal())
+ return;
+ if (!isSRegisterDefined(Reg))
+ llvm::report_fatal_error(std::string(InstName) + ": Can't find " + RegName);
+}
+
+void verifyDRegDefined(IValueT Reg, const char *RegName, const char *InstName) {
+ if (BuildDefs::minimal())
+ return;
+ if (!isDRegisterDefined(Reg))
+ llvm::report_fatal_error(std::string(InstName) + ": Can't find " + RegName);
+}
+
void verifyCondDefined(CondARM32::Cond Cond, const char *InstName) {
if (BuildDefs::minimal())
return;
@@ -631,7 +692,7 @@ void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT InstType,
verifyRegNotPcWhenSetFlags(Rd, SetFlags, InstName);
break;
}
- verifyRegDefined(Rd, "Rd", InstName);
+ verifyGPRegDefined(Rd, "Rd", InstName);
verifyCondDefined(Cond, InstName);
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
@@ -645,8 +706,8 @@ void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode,
const Operand *OpRd, const Operand *OpRn,
const Operand *OpSrc1, bool SetFlags,
EmitChecks RuleChecks, const char *InstName) {
- IValueT Rd = encodeRegister(OpRd, "Rd", InstName);
- IValueT Rn = encodeRegister(OpRn, "Rn", InstName);
+ IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
+ IValueT Rn = encodeGPRegister(OpRn, "Rn", InstName);
emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, RuleChecks, InstName);
}
@@ -656,7 +717,7 @@ void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode,
const char *InstName) {
IValueT Src1Value;
// TODO(kschimpf) Other possible decodings of data operations.
- switch (encodeOperand(OpSrc1, Src1Value)) {
+ switch (encodeOperand(OpSrc1, Src1Value, WantGPRegs)) {
default:
llvm::report_fatal_error(std::string(InstName) +
": Can't encode instruction");
@@ -758,14 +819,14 @@ void AssemblerARM32::emitCompareOp(CondARM32::Cond Cond, IValueT Opcode,
// defining RotatedImm8.
constexpr bool SetFlags = true;
constexpr IValueT Rd = RegARM32::Encoded_Reg_r0;
- IValueT Rn = encodeRegister(OpRn, "Rn", InstName);
+ IValueT Rn = encodeGPRegister(OpRn, "Rn", InstName);
emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, NoChecks, InstName);
}
void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, IValueT InstType,
bool IsLoad, bool IsByte, IValueT Rt,
IValueT Address, const char *InstName) {
- verifyRegDefined(Rt, "Rt", InstName);
+ verifyGPRegDefined(Rt, "Rt", InstName);
verifyCondDefined(Cond, InstName);
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
@@ -851,7 +912,7 @@ void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode,
// cccc000pu0wxnnnnttttiiiiyyyyjjjj where cccc=Cond, nnnn=Rn, tttt=Rt,
// iiiijjjj=Imm8, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode,
// and pu0w0nnnn0000iiii0000jjjj=Address.
- verifyRegDefined(Rt, "Rt", InstName);
+ verifyGPRegDefined(Rt, "Rt", InstName);
verifyCondDefined(Cond, InstName);
verifyPOrNotW(Address, InstName);
verifyRegNotPc(Rt, "Rt", InstName);
@@ -871,7 +932,7 @@ void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode,
// cccc000pu0wxnnnntttt00001011mmmm where cccc=Cond, tttt=Rt, nnnn=Rn,
// mmmm=Rm, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, and
// pu0w0nnnn000000000000mmmm=Address.
- verifyRegDefined(Rt, "Rt", InstName);
+ verifyGPRegDefined(Rt, "Rt", InstName);
verifyCondDefined(Cond, InstName);
verifyPOrNotW(Address, InstName);
verifyRegNotPc(Rt, "Rt", InstName);
@@ -896,9 +957,9 @@ void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode,
void AssemblerARM32::emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
IValueT Rn, IValueT Rm, const char *InstName) {
- verifyRegDefined(Rd, "Rd", InstName);
- verifyRegDefined(Rn, "Rn", InstName);
- verifyRegDefined(Rm, "Rm", InstName);
+ verifyGPRegDefined(Rd, "Rd", InstName);
+ verifyGPRegDefined(Rn, "Rn", InstName);
+ verifyGPRegDefined(Rm, "Rm", InstName);
verifyCondDefined(Cond, InstName);
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
const IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) |
@@ -911,10 +972,10 @@ void AssemblerARM32::emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
IValueT Rn, IValueT Rm, IValueT Rs,
bool SetFlags, const char *InstName) {
- verifyRegDefined(Rd, "Rd", InstName);
- verifyRegDefined(Rn, "Rn", InstName);
- verifyRegDefined(Rm, "Rm", InstName);
- verifyRegDefined(Rs, "Rs", InstName);
+ verifyGPRegDefined(Rd, "Rd", InstName);
+ verifyGPRegDefined(Rn, "Rn", InstName);
+ verifyGPRegDefined(Rm, "Rm", InstName);
+ verifyGPRegDefined(Rs, "Rs", InstName);
verifyCondDefined(Cond, InstName);
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) |
@@ -930,7 +991,7 @@ void AssemblerARM32::emitMultiMemOp(CondARM32::Cond Cond,
const char *InstName) {
constexpr IValueT NumGPRegisters = 16;
verifyCondDefined(Cond, InstName);
- verifyRegDefined(BaseReg, "base", InstName);
+ verifyGPRegDefined(BaseReg, "base", InstName);
if (Registers >= (1 << NumGPRegisters))
llvm::report_fatal_error(std::string(InstName) +
": Register set too large");
@@ -944,8 +1005,8 @@ void AssemblerARM32::emitMultiMemOp(CondARM32::Cond Cond,
void AssemblerARM32::emitSignExtend(CondARM32::Cond Cond, IValueT Opcode,
const Operand *OpRd, const Operand *OpSrc0,
const char *InstName) {
- IValueT Rd = encodeRegister(OpRd, "Rd", InstName);
- IValueT Rm = encodeRegister(OpSrc0, "Rm", InstName);
+ IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
+ IValueT Rm = encodeGPRegister(OpSrc0, "Rm", InstName);
// Note: For the moment, we assume no rotation is specified.
RotationValue Rotation = kRotateNone;
constexpr IValueT Rn = RegARM32::Encoded_Reg_pc;
@@ -988,6 +1049,40 @@ void AssemblerARM32::emitSignExtend(CondARM32::Cond Cond, IValueT Opcode,
emitInst(Encoding);
}
+void AssemblerARM32::emitVFPddd(CondARM32::Cond Cond, IValueT Opcode,
+ IValueT Dd, IValueT Dn, IValueT Dm,
+ const char *InstName) {
+ verifyDRegDefined(Dd, "Dd", InstName);
+ verifyDRegDefined(Dn, "Dn", InstName);
+ verifyDRegDefined(Dm, "Dm", InstName);
+ verifyCondDefined(Cond, InstName);
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9 | B8;
+ const IValueT Encoding =
+ Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) |
+ (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) |
+ (getXXXXInRegYXXXX(Dn) << 12) | (getYInRegYXXXX(Dn) << 7) |
+ (getYInRegYXXXX(Dm) << 5) | getXXXXInRegYXXXX(Dm);
+ emitInst(Encoding);
+}
+
+void AssemblerARM32::emitVFPsss(CondARM32::Cond Cond, IValueT Opcode,
+ IValueT Sd, IValueT Sn, IValueT Sm,
+ const char *InstName) {
+ verifySRegDefined(Sd, "Sd", InstName);
+ verifySRegDefined(Sn, "Sn", InstName);
+ verifySRegDefined(Sm, "Sm", InstName);
+ verifyCondDefined(Cond, InstName);
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9;
+ const IValueT Encoding =
+ Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) |
+ (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sn) << 16) |
+ (getXXXXInRegXXXXY(Sd) << 12) | (getYInRegXXXXY(Sn) << 7) |
+ (getYInRegXXXXY(Sm) << 5) | getXXXXInRegXXXXY(Sm);
+ emitInst(Encoding);
+}
+
void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn,
const Operand *OpSrc1, bool SetFlags,
CondARM32::Cond Cond) {
@@ -1108,7 +1203,7 @@ void AssemblerARM32::blx(const Operand *Target) {
// cccc000100101111111111110011mmmm where cccc=Cond (not currently allowed)
// and mmmm=Rm.
constexpr const char *BlxName = "Blx";
- IValueT Rm = encodeRegister(Target, "Rm", BlxName);
+ IValueT Rm = encodeGPRegister(Target, "Rm", BlxName);
verifyRegNotPc(Rm, "Rm", BlxName);
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
constexpr CondARM32::Cond Cond = CondARM32::AL;
@@ -1124,7 +1219,7 @@ void AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) {
// cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond.
constexpr const char *BxName = "bx";
verifyCondDefined(Cond, BxName);
- verifyRegDefined(Rm, "Rm", BxName);
+ verifyGPRegDefined(Rm, "Rm", BxName);
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B24 |
B21 | (0xfff << 8) | B4 |
@@ -1141,11 +1236,11 @@ void AssemblerARM32::clz(const Operand *OpRd, const Operand *OpSrc,
constexpr const char *ClzName = "clz";
constexpr const char *RdName = "Rd";
constexpr const char *RmName = "Rm";
- IValueT Rd = encodeRegister(OpRd, RdName, ClzName);
- verifyRegDefined(Rd, RdName, ClzName);
+ IValueT Rd = encodeGPRegister(OpRd, RdName, ClzName);
+ verifyGPRegDefined(Rd, RdName, ClzName);
verifyRegNotPc(Rd, RdName, ClzName);
- IValueT Rm = encodeRegister(OpSrc, RmName, ClzName);
- verifyRegDefined(Rm, RmName, ClzName);
+ IValueT Rm = encodeGPRegister(OpSrc, RmName, ClzName);
+ verifyGPRegDefined(Rm, RmName, ClzName);
verifyRegNotPc(Rm, RmName, ClzName);
verifyCondDefined(Cond, ClzName);
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
@@ -1230,7 +1325,7 @@ void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress,
CondARM32::Cond Cond, const TargetInfo &TInfo) {
constexpr const char *LdrName = "ldr";
constexpr bool IsLoad = true;
- IValueT Rt = encodeRegister(OpRt, "Rt", LdrName);
+ IValueT Rt = encodeGPRegister(OpRt, "Rt", LdrName);
const Type Ty = OpRt->getType();
switch (Ty) {
case IceType_i64:
@@ -1303,7 +1398,7 @@ void AssemblerARM32::emitMemExOp(CondARM32::Cond Cond, Type Ty, bool IsLoad,
const Operand *OpAddress,
const TargetInfo &TInfo,
const char *InstName) {
- IValueT Rd = encodeRegister(OpRd, "Rd", InstName);
+ IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
IValueT MemExOpcode = IsLoad ? B0 : 0;
switch (Ty) {
default:
@@ -1327,8 +1422,8 @@ void AssemblerARM32::emitMemExOp(CondARM32::Cond Cond, Type Ty, bool IsLoad,
llvm::report_fatal_error(std::string(InstName) +
": Can't extract Rn from address");
assert(Utils::IsAbsoluteUint(3, MemExOpcode));
- verifyRegDefined(Rd, "Rd", InstName);
- verifyRegDefined(Rt, "Rt", InstName);
+ verifyGPRegDefined(Rd, "Rd", InstName);
+ verifyGPRegDefined(Rt, "Rt", InstName);
verifyCondDefined(Cond, InstName);
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
IValueT Encoding = (Cond << kConditionShift) | B24 | B23 | B11 | B10 | B9 |
@@ -1372,10 +1467,10 @@ void AssemblerARM32::emitShift(const CondARM32::Cond Cond,
const Operand *OpSrc1, const bool SetFlags,
const char *InstName) {
constexpr IValueT ShiftOpcode = B3 | B2 | B0; // 1101
- IValueT Rd = encodeRegister(OpRd, "Rd", InstName);
- IValueT Rm = encodeRegister(OpRm, "Rm", InstName);
+ IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
+ IValueT Rm = encodeGPRegister(OpRm, "Rm", InstName);
IValueT Value;
- switch (encodeOperand(OpSrc1, Value)) {
+ switch (encodeOperand(OpSrc1, Value, WantGPRegs)) {
default:
llvm::report_fatal_error(std::string(InstName) +
": Last operand not understood");
@@ -1398,7 +1493,7 @@ void AssemblerARM32::emitShift(const CondARM32::Cond Cond,
// cccc0001101s0000ddddssss0001mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
// mmmm=Rm, and ssss=Rs.
constexpr IValueT Rn = 0; // Rn field is not used.
- IValueT Rs = encodeRegister(OpSrc1, "Rs", InstName);
+ IValueT Rs = encodeGPRegister(OpSrc1, "Rs", InstName);
verifyRegNotPc(Rd, "Rd", InstName);
verifyRegNotPc(Rm, "Rm", InstName);
verifyRegNotPc(Rs, "Rs", InstName);
@@ -1445,7 +1540,7 @@ void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
// and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this
// assembler.
constexpr const char *MovName = "mov";
- IValueT Rd = encodeRegister(OpRd, "Rd", MovName);
+ IValueT Rd = encodeGPRegister(OpRd, "Rd", MovName);
constexpr bool SetFlags = false;
constexpr IValueT Rn = 0;
constexpr IValueT MovOpcode = B3 | B2 | B0; // 1101.
@@ -1457,14 +1552,14 @@ void AssemblerARM32::emitMovwt(CondARM32::Cond Cond, bool IsMovW,
const Operand *OpRd, const Operand *OpSrc,
const char *MovName) {
IValueT Opcode = B25 | B24 | (IsMovW ? 0 : B22);
- IValueT Rd = encodeRegister(OpRd, "Rd", MovName);
+ IValueT Rd = encodeGPRegister(OpRd, "Rd", MovName);
IValueT Imm16;
if (const auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) {
emitFixup(createMoveFixup(IsMovW, Src));
// Use 0 for the lower 16 bits of the relocatable, and add a fixup to
// install the correct bits.
Imm16 = 0;
- } else if (encodeOperand(OpSrc, Imm16) != EncodedAsConstI32) {
+ } else if (encodeOperand(OpSrc, Imm16, WantGPRegs) != EncodedAsConstI32) {
llvm::report_fatal_error(std::string(MovName) + ": Not i32 constant");
}
verifyCondDefined(Cond, MovName);
@@ -1515,7 +1610,7 @@ void AssemblerARM32::mvn(const Operand *OpRd, const Operand *OpSrc,
// cccc0001111s0000ddddiiiiitt0mmmm where cccc=Cond, s=SetFlags=0, dddd=Rd,
// mmmm=Rm, iiii defines shift constant, and tt=ShiftKind.
constexpr const char *MvnName = "mvn";
- IValueT Rd = encodeRegister(OpRd, "Rd", MvnName);
+ IValueT Rd = encodeGPRegister(OpRd, "Rd", MvnName);
constexpr IValueT MvnOpcode = B3 | B2 | B1 | B0; // i.e. 1111
constexpr IValueT Rn = 0;
constexpr bool SetFlags = false;
@@ -1563,9 +1658,9 @@ void AssemblerARM32::sdiv(const Operand *OpRd, const Operand *OpRn,
// cccc01110001dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and
// mmmm=Rm.
constexpr const char *SdivName = "sdiv";
- IValueT Rd = encodeRegister(OpRd, "Rd", SdivName);
- IValueT Rn = encodeRegister(OpRn, "Rn", SdivName);
- IValueT Rm = encodeRegister(OpSrc1, "Rm", SdivName);
+ IValueT Rd = encodeGPRegister(OpRd, "Rd", SdivName);
+ IValueT Rn = encodeGPRegister(OpRn, "Rn", SdivName);
+ IValueT Rm = encodeGPRegister(OpSrc1, "Rm", SdivName);
verifyRegNotPc(Rd, "Rd", SdivName);
verifyRegNotPc(Rn, "Rn", SdivName);
verifyRegNotPc(Rm, "Rm", SdivName);
@@ -1578,7 +1673,7 @@ void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress,
CondARM32::Cond Cond, const TargetInfo &TInfo) {
constexpr const char *StrName = "str";
constexpr bool IsLoad = false;
- IValueT Rt = encodeRegister(OpRt, "Rt", StrName);
+ IValueT Rt = encodeGPRegister(OpRt, "Rt", StrName);
const Type Ty = OpRt->getType();
switch (Ty) {
case IceType_i64:
@@ -1662,7 +1757,7 @@ void AssemblerARM32::strex(const Operand *OpRd, const Operand *OpRt,
// nnnn=Rn.
constexpr const char *StrexName = "strex";
// Note: Rt uses Rm shift in encoding.
- IValueT Rt = encodeRegister(OpRt, "Rt", StrexName);
+ IValueT Rt = encodeGPRegister(OpRt, "Rt", StrexName);
const Type Ty = OpRt->getType();
constexpr bool IsLoad = true;
emitMemExOp(Cond, Ty, !IsLoad, OpRd, Rt, OpAddress, TInfo, StrexName);
@@ -1694,7 +1789,7 @@ void AssemblerARM32::pop(const Operand *OpRt, CondARM32::Cond Cond) {
//
// cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond.
constexpr const char *Pop = "pop";
- IValueT Rt = encodeRegister(OpRt, "Rt", Pop);
+ IValueT Rt = encodeGPRegister(OpRt, "Rt", Pop);
verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Pop);
// Same as load instruction.
constexpr bool IsLoad = true;
@@ -1722,7 +1817,7 @@ void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) {
//
// cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond.
constexpr const char *Push = "push";
- IValueT Rt = encodeRegister(OpRt, "Rt", Push);
+ IValueT Rt = encodeGPRegister(OpRt, "Rt", Push);
verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Push);
// Same as store instruction.
constexpr bool isLoad = false;
@@ -1753,10 +1848,10 @@ void AssemblerARM32::mla(const Operand *OpRd, const Operand *OpRn,
// cccc0000001sddddaaaammmm1001nnnn where cccc=Cond, s=SetFlags, dddd=Rd,
// aaaa=Ra, mmmm=Rm, and nnnn=Rn.
constexpr const char *MlaName = "mla";
- IValueT Rd = encodeRegister(OpRd, "Rd", MlaName);
- IValueT Rn = encodeRegister(OpRn, "Rn", MlaName);
- IValueT Rm = encodeRegister(OpRm, "Rm", MlaName);
- IValueT Ra = encodeRegister(OpRa, "Ra", MlaName);
+ IValueT Rd = encodeGPRegister(OpRd, "Rd", MlaName);
+ IValueT Rn = encodeGPRegister(OpRn, "Rn", MlaName);
+ IValueT Rm = encodeGPRegister(OpRm, "Rm", MlaName);
+ IValueT Ra = encodeGPRegister(OpRa, "Ra", MlaName);
verifyRegNotPc(Rd, "Rd", MlaName);
verifyRegNotPc(Rn, "Rn", MlaName);
verifyRegNotPc(Rm, "Rm", MlaName);
@@ -1771,10 +1866,10 @@ void AssemblerARM32::mls(const Operand *OpRd, const Operand *OpRn,
const Operand *OpRm, const Operand *OpRa,
CondARM32::Cond Cond) {
constexpr const char *MlsName = "mls";
- IValueT Rd = encodeRegister(OpRd, "Rd", MlsName);
- IValueT Rn = encodeRegister(OpRn, "Rn", MlsName);
- IValueT Rm = encodeRegister(OpRm, "Rm", MlsName);
- IValueT Ra = encodeRegister(OpRa, "Ra", MlsName);
+ IValueT Rd = encodeGPRegister(OpRd, "Rd", MlsName);
+ IValueT Rn = encodeGPRegister(OpRn, "Rn", MlsName);
+ IValueT Rm = encodeGPRegister(OpRm, "Rm", MlsName);
+ IValueT Ra = encodeGPRegister(OpRa, "Ra", MlsName);
verifyRegNotPc(Rd, "Rd", MlsName);
verifyRegNotPc(Rn, "Rn", MlsName);
verifyRegNotPc(Rm, "Rm", MlsName);
@@ -1794,9 +1889,9 @@ void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn,
// cccc0000000sdddd0000mmmm1001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn,
// mmmm=Rm, and s=SetFlags.
constexpr const char *MulName = "mul";
- IValueT Rd = encodeRegister(OpRd, "Rd", MulName);
- IValueT Rn = encodeRegister(OpRn, "Rn", MulName);
- IValueT Rm = encodeRegister(OpSrc1, "Rm", MulName);
+ IValueT Rd = encodeGPRegister(OpRd, "Rd", MulName);
+ IValueT Rn = encodeGPRegister(OpRn, "Rn", MulName);
+ IValueT Rm = encodeGPRegister(OpSrc1, "Rm", MulName);
verifyRegNotPc(Rd, "Rd", MulName);
verifyRegNotPc(Rn, "Rn", MulName);
verifyRegNotPc(Rm, "Rm", MulName);
@@ -1809,8 +1904,8 @@ void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn,
void AssemblerARM32::emitRdRm(CondARM32::Cond Cond, IValueT Opcode,
const Operand *OpRd, const Operand *OpRm,
const char *InstName) {
- IValueT Rd = encodeRegister(OpRd, "Rd", InstName);
- IValueT Rm = encodeRegister(OpRm, "Rm", InstName);
+ IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
+ IValueT Rm = encodeGPRegister(OpRm, "Rm", InstName);
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
IValueT Encoding =
(Cond << kConditionShift) | Opcode | (Rd << kRdShift) | (Rm << kRmShift);
@@ -1965,9 +2060,9 @@ void AssemblerARM32::udiv(const Operand *OpRd, const Operand *OpRn,
// cccc01110011dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and
// mmmm=Rm.
constexpr const char *UdivName = "udiv";
- IValueT Rd = encodeRegister(OpRd, "Rd", UdivName);
- IValueT Rn = encodeRegister(OpRn, "Rn", UdivName);
- IValueT Rm = encodeRegister(OpSrc1, "Rm", UdivName);
+ IValueT Rd = encodeGPRegister(OpRd, "Rd", UdivName);
+ IValueT Rn = encodeGPRegister(OpRn, "Rn", UdivName);
+ IValueT Rm = encodeGPRegister(OpSrc1, "Rm", UdivName);
verifyRegNotPc(Rd, "Rd", UdivName);
verifyRegNotPc(Rn, "Rn", UdivName);
verifyRegNotPc(Rm, "Rm", UdivName);
@@ -1985,10 +2080,10 @@ void AssemblerARM32::umull(const Operand *OpRdLo, const Operand *OpRdHi,
// cccc0000100shhhhllllmmmm1001nnnn where hhhh=RdHi, llll=RdLo, nnnn=Rn,
// mmmm=Rm, and s=SetFlags
constexpr const char *UmullName = "umull";
- IValueT RdLo = encodeRegister(OpRdLo, "RdLo", UmullName);
- IValueT RdHi = encodeRegister(OpRdHi, "RdHi", UmullName);
- IValueT Rn = encodeRegister(OpRn, "Rn", UmullName);
- IValueT Rm = encodeRegister(OpRm, "Rm", UmullName);
+ IValueT RdLo = encodeGPRegister(OpRdLo, "RdLo", UmullName);
+ IValueT RdHi = encodeGPRegister(OpRdHi, "RdHi", UmullName);
+ IValueT Rn = encodeGPRegister(OpRn, "Rn", UmullName);
+ IValueT Rm = encodeGPRegister(OpRm, "Rm", UmullName);
verifyRegNotPc(RdLo, "RdLo", UmullName);
verifyRegNotPc(RdHi, "RdHi", UmullName);
verifyRegNotPc(Rn, "Rn", UmullName);
@@ -2006,6 +2101,36 @@ void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0,
emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName);
}
+void AssemblerARM32::vadds(const Operand *OpSd, const Operand *OpSn,
+ const Operand *OpSm, CondARM32::Cond Cond) {
+ // VADD (floating-point) - ARM section A8.8.283, encoding A2:
+ // vadd<c>.f32 <Sd>, <Sn>, <Sm>
+ //
+ // cccc11100D11nnnndddd101sN0M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn,
+ // and mmmmM=Rm.
+ constexpr const char *Vadds = "vadds";
+ IValueT Sd = encodeSRegister(OpSd, "Sd", Vadds);
+ IValueT Sn = encodeSRegister(OpSn, "Sn", Vadds);
+ IValueT Sm = encodeSRegister(OpSm, "Sm", Vadds);
+ constexpr IValueT VaddsOpcode = B21 | B20;
+ emitVFPsss(Cond, VaddsOpcode, Sd, Sn, Sm, Vadds);
+}
+
+void AssemblerARM32::vaddd(const Operand *OpDd, const Operand *OpDn,
+ const Operand *OpDm, CondARM32::Cond Cond) {
+ // VADD (floating-point) - ARM section A8.8.283, encoding A2:
+ // vadd<c>.f64 <Dd>, <Dn>, <Dm>
+ //
+ // cccc11100D11nnnndddd101sN0M0mmmm where cccc=Cond, s=1, Ddddd=Rd, Nnnnn=Rn,
+ // and Mmmmm=Rm.
+ constexpr const char *Vaddd = "vaddd";
+ IValueT Dd = encodeDRegister(OpDd, "Dd", Vaddd);
+ IValueT Dn = encodeDRegister(OpDn, "Dn", Vaddd);
+ IValueT Dm = encodeDRegister(OpDm, "Dm", Vaddd);
+ constexpr IValueT VadddOpcode = B21 | B20;
+ emitVFPddd(Cond, VadddOpcode, Dd, Dn, Dm, Vaddd);
+}
+
void AssemblerARM32::emitVStackOp(CondARM32::Cond Cond, IValueT Opcode,
const Variable *OpBaseReg,
SizeT NumConsecRegs, const char *InstName) {
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.h » ('j') | src/IceRegistersARM32.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698