Index: src/IceAssemblerARM32.cpp |
diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp |
index 2195d4d985766074c3dea6391637ad61e8c0c167..9972b44f29506f286618f931909fffdcca5422d9 100644 |
--- a/src/IceAssemblerARM32.cpp |
+++ b/src/IceAssemblerARM32.cpp |
@@ -28,6 +28,7 @@ using namespace Ice; |
// The following define individual bits. |
static constexpr uint32_t B0 = 1; |
+static constexpr uint32_t B1 = 1 << 1; |
static constexpr uint32_t B2 = 1 << 2; |
static constexpr uint32_t B3 = 1 << 3; |
static constexpr uint32_t B4 = 1 << 4; |
@@ -220,4 +221,34 @@ void ARM32::AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc, |
UnimplementedError(Ctx->getFlags()); |
} |
+void ARM32::AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, |
+ const Operand *OpSrc1, bool SetFlags, |
+ CondARM32::Cond Cond) { |
+ // Note: Loop is used so that we can short circuit using break; |
+ do { |
+ uint32_t Rd; |
+ if (decode(OpRd, Rd) != DecodedAsRegister) |
+ break; |
+ uint32_t Rn; |
+ if (decode(OpRn, Rn) != DecodedAsRegister) |
+ break; |
+ uint32_t Src1Value; |
+ // TODO(kschimpf) Other possible decodings of add. |
+ if (decode(OpSrc1, Src1Value) == DecodedAsRotatedImm8) { |
+ // Sub (Immediate): See ARM section A8.8.222, rule A1. |
+ // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
+ // s=SetFlags and iiiiiiiiiiii=Src1Value |
+ if (!isConditionDefined(Cond) || (Rd == RegARM32::Reg_pc && SetFlags) || |
+ (Rn == RegARM32::Reg_lr) || (Rn == RegARM32::Reg_pc && SetFlags)) |
+ // Conditions of rule violated. |
+ break; |
+ uint32_t Add = B1; // 0010 |
+ uint32_t InstType = 1; |
+ emitType01(Cond, InstType, Add, SetFlags, Rn, Rd, Src1Value); |
+ return; |
+ } |
+ } while (0); |
+ UnimplementedError(Ctx->getFlags()); |
+} |
+ |
} // end of namespace Ice |