1 #pragma once 2 3 #include <string.h> 4 #include <functional> 5 #include <map> 6 #include <vector> 7 #include "Literal128.h" 8 #include "Stream.h" 9 #include "Types.h" 10 11 class CAArch32Assembler 12 { 13 public: 14 enum REGISTER 15 { 16 r0 = 0, 17 r1 = 1, 18 r2 = 2, 19 r3 = 3, 20 r4 = 4, 21 r5 = 5, 22 r6 = 6, 23 r7 = 7, 24 r8 = 8, 25 r9 = 9, 26 r10 = 10, 27 r11 = 11, 28 r12 = 12, 29 r13 = 13, 30 r14 = 14, 31 r15 = 15, 32 33 rIP = 12, 34 rSP = 13, 35 rLR = 14, 36 rPC = 15, 37 }; 38 39 enum SINGLE_REGISTER 40 { 41 s0, s1, s2, s3, 42 s4, s5, s6, s7, 43 s8, s9, s10, s11, 44 s12, s13, s14, s15, 45 46 s16, s17, s18, s19, 47 s20, s21, s22, s23, 48 s24, s25, s26, s27, 49 s28, s29, s30, s31, 50 }; 51 52 enum DOUBLE_REGISTER 53 { 54 d0, d1, d2, d3, 55 d4, d5, d6, d7, 56 d8, d9, d10, d11, 57 d12, d13, d14, d15, 58 59 d16, d17, d18, d19, 60 d20, d21, d22, d23, 61 d24, d25, d26, d27, 62 d28, d29, d30, d31, 63 }; 64 65 enum QUAD_REGISTER 66 { 67 q0 = 0, q1 = 2, q2 = 4, q3 = 6, 68 q4 = 8, q5 = 10, q6 = 12, q7 = 14, 69 q8 = 16, q9 = 18, q10 = 20, q11 = 22, 70 q12 = 24, q13 = 26, q14 = 28, q15 = 30, 71 }; 72 73 enum ALU_OPCODE 74 { 75 ALU_OPCODE_AND = 0x00, 76 ALU_OPCODE_EOR = 0x01, 77 ALU_OPCODE_SUB = 0x02, 78 ALU_OPCODE_RSB = 0x03, 79 ALU_OPCODE_ADD = 0x04, 80 ALU_OPCODE_ADC = 0x05, 81 ALU_OPCODE_SBC = 0x06, 82 ALU_OPCODE_RSC = 0x07, 83 ALU_OPCODE_TST = 0x08, 84 ALU_OPCODE_TEQ = 0x09, 85 ALU_OPCODE_CMP = 0x0A, 86 ALU_OPCODE_CMN = 0x0B, 87 ALU_OPCODE_ORR = 0x0C, 88 ALU_OPCODE_MOV = 0x0D, 89 ALU_OPCODE_BIC = 0x0E, 90 ALU_OPCODE_MVN = 0x0F, 91 }; 92 93 enum CONDITION 94 { 95 CONDITION_EQ = 0x00, 96 CONDITION_NE = 0x01, 97 CONDITION_CS = 0x02, 98 CONDITION_CC = 0x03, 99 CONDITION_MI = 0x04, 100 CONDITION_PL = 0x05, 101 CONDITION_VS = 0x06, 102 CONDITION_VC = 0x07, 103 CONDITION_HI = 0x08, 104 CONDITION_LS = 0x09, 105 CONDITION_GE = 0x0A, 106 CONDITION_LT = 0x0B, 107 CONDITION_GT = 0x0C, 108 CONDITION_LE = 0x0D, 109 CONDITION_AL = 0x0E, 110 CONDITION_NV = 0x0F 111 }; 112 113 enum SHIFT 114 { 115 SHIFT_LSL = 0x00, 116 SHIFT_LSR = 0x01, 117 SHIFT_ASR = 0x02, 118 SHIFT_ROR = 0x03, 119 }; 120 121 struct InstructionAlu 122 { InstructionAluInstructionAlu123 InstructionAlu() 124 { 125 memset(this, 0, sizeof(InstructionAlu)); 126 } 127 128 unsigned int operand : 12; 129 unsigned int rd : 4; 130 unsigned int rn : 4; 131 unsigned int setFlags : 1; 132 unsigned int opcode : 4; 133 unsigned int immediate : 1; 134 unsigned int reserved : 2; 135 unsigned int condition : 4; 136 }; 137 138 struct ImmediateAluOperand 139 { 140 unsigned int immediate : 8; 141 unsigned int rotate : 4; 142 }; 143 144 struct RegisterAluOperand 145 { 146 unsigned int rm : 4; 147 unsigned int shift : 8; 148 }; 149 150 struct AluLdrShift 151 { 152 unsigned int typeBit : 1; 153 unsigned int type : 2; 154 unsigned int amount : 5; 155 }; 156 157 struct ShiftRmAddress 158 { 159 union 160 { 161 struct 162 { 163 unsigned int rm : 4; 164 unsigned int isConstant : 1; 165 unsigned int shiftType : 2; 166 unsigned int constant : 5; 167 } immediateShift; 168 struct 169 { 170 unsigned int rm : 4; 171 unsigned int isConstant : 1; 172 unsigned int shiftType : 2; 173 unsigned int zero : 1; 174 unsigned int rs : 4; 175 } registerShift; 176 }; 177 }; 178 179 struct LdrAddress 180 { 181 union 182 { 183 uint16 immediate; 184 ShiftRmAddress shiftRm; 185 }; 186 bool isImmediate = false; 187 bool isNegative = false; 188 }; 189 190 typedef unsigned int LABEL; 191 192 193 virtual ~CAArch32Assembler() = default; 194 195 void SetStream(Framework::CStream*); 196 197 LABEL CreateLabel(); 198 void ClearLabels(); 199 void MarkLabel(LABEL); 200 void ResolveLabelReferences(); 201 202 void ResolveLiteralReferences(); 203 204 void Adc(REGISTER, REGISTER, REGISTER); 205 void Add(REGISTER, REGISTER, REGISTER); 206 void Add(REGISTER, REGISTER, const ImmediateAluOperand&); 207 void Adds(REGISTER, REGISTER, REGISTER); 208 void Adrl(REGISTER, const LITERAL128&); 209 void And(REGISTER, REGISTER, REGISTER); 210 void And(REGISTER, REGISTER, const ImmediateAluOperand&); 211 void BCc(CONDITION, LABEL); 212 void Bic(REGISTER, REGISTER, const ImmediateAluOperand&); 213 void Bx(REGISTER); 214 void Blx(REGISTER); 215 void Clz(REGISTER, REGISTER); 216 void Cmn(REGISTER, const ImmediateAluOperand&); 217 void Cmp(REGISTER, REGISTER); 218 void Cmp(REGISTER, const ImmediateAluOperand&); 219 void Eor(REGISTER, REGISTER, REGISTER); 220 void Eor(REGISTER, REGISTER, const ImmediateAluOperand&); 221 void Ldmia(REGISTER, uint16); 222 void Ldr(REGISTER, REGISTER, const LdrAddress&); 223 void Ldrb(REGISTER, REGISTER, const LdrAddress&); 224 void Ldrh(REGISTER, REGISTER, const LdrAddress&); 225 void Ldr_Pc(REGISTER, int32); 226 void Ldrd(REGISTER, REGISTER, const LdrAddress&); 227 void Mov(REGISTER, REGISTER); 228 void Mov(REGISTER, const RegisterAluOperand&); 229 void Mov(REGISTER, const ImmediateAluOperand&); 230 void MovCc(CONDITION, REGISTER, const ImmediateAluOperand&); 231 void Movw(REGISTER, uint16); 232 void Movt(REGISTER, uint16); 233 void Mvn(REGISTER, REGISTER); 234 void Mvn(REGISTER, const ImmediateAluOperand&); 235 void Or(REGISTER, REGISTER, REGISTER); 236 void Or(REGISTER, REGISTER, const ImmediateAluOperand&); 237 void Or(CONDITION, REGISTER, REGISTER, const ImmediateAluOperand&); 238 void Rsb(REGISTER, REGISTER, const ImmediateAluOperand&); 239 void Sbc(REGISTER, REGISTER, REGISTER); 240 void Sdiv(REGISTER, REGISTER, REGISTER); 241 void Smull(REGISTER, REGISTER, REGISTER, REGISTER); 242 void Stmdb(REGISTER, uint16); 243 void Str(REGISTER, REGISTER, const LdrAddress&); 244 void Strb(REGISTER, REGISTER, const LdrAddress&); 245 void Strh(REGISTER, REGISTER, const LdrAddress&); 246 void Strd(REGISTER, REGISTER, const LdrAddress&); 247 void Sub(REGISTER, REGISTER, REGISTER); 248 void Sub(REGISTER, REGISTER, const ImmediateAluOperand&); 249 void Subs(REGISTER, REGISTER, REGISTER); 250 void Teq(REGISTER, const ImmediateAluOperand&); 251 void Tst(REGISTER, REGISTER); 252 void Udiv(REGISTER, REGISTER, REGISTER); 253 void Umull(REGISTER, REGISTER, REGISTER, REGISTER); 254 255 //VFP/NEON 256 void Vldr(SINGLE_REGISTER, REGISTER, const LdrAddress&); 257 void Vld1_32x2(DOUBLE_REGISTER, REGISTER); 258 void Vld1_32x4(QUAD_REGISTER, REGISTER); 259 void Vld1_32x4_u(QUAD_REGISTER, REGISTER); 260 void Vstr(SINGLE_REGISTER, REGISTER, const LdrAddress&); 261 void Vst1_32x4(QUAD_REGISTER, REGISTER); 262 void Vmov(DOUBLE_REGISTER, REGISTER, uint8); 263 void Vmov(REGISTER, DOUBLE_REGISTER, uint8); 264 void Vmovn_I16(DOUBLE_REGISTER, QUAD_REGISTER); 265 void Vmovn_I32(DOUBLE_REGISTER, QUAD_REGISTER); 266 void Vdup(QUAD_REGISTER, REGISTER); 267 void Vzip_I8(DOUBLE_REGISTER, DOUBLE_REGISTER); 268 void Vzip_I16(DOUBLE_REGISTER, DOUBLE_REGISTER); 269 void Vzip_I32(QUAD_REGISTER, QUAD_REGISTER); 270 void Vtbl(DOUBLE_REGISTER, DOUBLE_REGISTER, DOUBLE_REGISTER); 271 void Vadd_F32(SINGLE_REGISTER, SINGLE_REGISTER, SINGLE_REGISTER); 272 void Vadd_F32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 273 void Vadd_I8(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 274 void Vadd_I16(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 275 void Vadd_I32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 276 void Vpaddl_I8(QUAD_REGISTER, QUAD_REGISTER); 277 void Vpaddl_I16(QUAD_REGISTER, QUAD_REGISTER); 278 void Vpaddl_I32(QUAD_REGISTER, QUAD_REGISTER); 279 void Vqadd_U8(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 280 void Vqadd_U16(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 281 void Vqadd_U32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 282 void Vqadd_I8(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 283 void Vqadd_I16(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 284 void Vqadd_I32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 285 void Vsub_F32(SINGLE_REGISTER, SINGLE_REGISTER, SINGLE_REGISTER); 286 void Vsub_F32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 287 void Vsub_I8(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 288 void Vsub_I16(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 289 void Vsub_I32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 290 void Vqsub_U8(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 291 void Vqsub_U16(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 292 void Vqsub_U32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 293 void Vqsub_I16(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 294 void Vqsub_I32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 295 void Vmul_F32(SINGLE_REGISTER, SINGLE_REGISTER, SINGLE_REGISTER); 296 void Vmul_F32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 297 void Vdiv_F32(SINGLE_REGISTER, SINGLE_REGISTER, SINGLE_REGISTER); 298 void Vand(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 299 void Vorn(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 300 void Vorr(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 301 void Veor(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 302 void Vmvn(QUAD_REGISTER, QUAD_REGISTER); 303 void Vshl_I16(QUAD_REGISTER, QUAD_REGISTER, uint8); 304 void Vshl_I32(QUAD_REGISTER, QUAD_REGISTER, uint8); 305 void Vshr_U16(QUAD_REGISTER, QUAD_REGISTER, uint8); 306 void Vshr_U32(QUAD_REGISTER, QUAD_REGISTER, uint8); 307 void Vshr_I16(QUAD_REGISTER, QUAD_REGISTER, uint8); 308 void Vshr_I32(QUAD_REGISTER, QUAD_REGISTER, uint8); 309 void Vabs_F32(SINGLE_REGISTER, SINGLE_REGISTER); 310 void Vabs_F32(QUAD_REGISTER, QUAD_REGISTER); 311 void Vneg_F32(SINGLE_REGISTER, SINGLE_REGISTER); 312 void Vsqrt_F32(SINGLE_REGISTER, SINGLE_REGISTER); 313 void Vceq_I8(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 314 void Vceq_I16(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 315 void Vceq_I32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 316 void Vceqz_F32(QUAD_REGISTER, QUAD_REGISTER); 317 void Vcge_F32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 318 void Vcgt_I8(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 319 void Vcgt_I16(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 320 void Vcgt_I32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 321 void Vcgt_F32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 322 void Vcltz_I32(QUAD_REGISTER, QUAD_REGISTER); 323 void Vcmp_F32(SINGLE_REGISTER, SINGLE_REGISTER); 324 void Vcmpz_F32(SINGLE_REGISTER); 325 void Vcvt_F32_S32(SINGLE_REGISTER, SINGLE_REGISTER); 326 void Vcvt_F32_S32(QUAD_REGISTER, QUAD_REGISTER); 327 void Vcvt_S32_F32(SINGLE_REGISTER, SINGLE_REGISTER); 328 void Vcvt_S32_F32(QUAD_REGISTER, QUAD_REGISTER); 329 void Vmrs(REGISTER); 330 331 void Vrecpe_F32(QUAD_REGISTER, QUAD_REGISTER); 332 void Vrecps_F32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 333 void Vrsqrte_F32(QUAD_REGISTER, QUAD_REGISTER); 334 void Vrsqrts_F32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 335 void Vmin_F32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 336 void Vmin_I16(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 337 void Vmin_I32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 338 void Vmax_F32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 339 void Vmax_I16(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 340 void Vmax_I32(QUAD_REGISTER, QUAD_REGISTER, QUAD_REGISTER); 341 342 static LdrAddress MakeImmediateLdrAddress(int32); 343 static LdrAddress MakeRegisterLdrAddress(REGISTER, SHIFT = SHIFT_LSL, uint8 = 0); 344 345 static ImmediateAluOperand MakeImmediateAluOperand(uint8, uint8); 346 static RegisterAluOperand MakeRegisterAluOperand(CAArch32Assembler::REGISTER, const AluLdrShift&); 347 348 static AluLdrShift MakeConstantShift(CAArch32Assembler::SHIFT, uint8); 349 static AluLdrShift MakeVariableShift(CAArch32Assembler::SHIFT, CAArch32Assembler::REGISTER); 350 351 private: 352 typedef size_t LABELREF; 353 354 struct LITERAL128REF 355 { 356 size_t offset = 0; 357 REGISTER rd = CAArch32Assembler::r0; 358 LITERAL128 value = LITERAL128(0, 0); 359 }; 360 361 typedef std::map<LABEL, size_t> LabelMapType; 362 typedef std::multimap<LABEL, LABELREF> LabelReferenceMapType; 363 364 typedef std::vector<LITERAL128REF> Literal128ArrayType; 365 366 void GenericAlu(ALU_OPCODE, bool, REGISTER, REGISTER, REGISTER); 367 void GenericAlu(ALU_OPCODE, bool, REGISTER, REGISTER, const ImmediateAluOperand&, CONDITION = CONDITION_AL); 368 369 void CreateLabelReference(LABEL); 370 void WriteWord(uint32); 371 372 static uint32 FPSIMD_EncodeSd(SINGLE_REGISTER); 373 static uint32 FPSIMD_EncodeSn(SINGLE_REGISTER); 374 static uint32 FPSIMD_EncodeSm(SINGLE_REGISTER); 375 static uint32 FPSIMD_EncodeDd(DOUBLE_REGISTER); 376 static uint32 FPSIMD_EncodeDn(DOUBLE_REGISTER); 377 static uint32 FPSIMD_EncodeDm(DOUBLE_REGISTER); 378 static uint32 FPSIMD_EncodeQd(QUAD_REGISTER); 379 static uint32 FPSIMD_EncodeQn(QUAD_REGISTER); 380 static uint32 FPSIMD_EncodeQm(QUAD_REGISTER); 381 382 unsigned int m_nextLabelId = 1; 383 LabelMapType m_labels; 384 LabelReferenceMapType m_labelReferences; 385 Literal128ArrayType m_literal128Refs; 386 387 Framework::CStream* m_stream = nullptr; 388 }; 389