} {}, , # ; T1 if (!size.IsNarrow() && immediate_t32.IsValid() && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADC{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x02a00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADC{} {}, , ; T1 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADC{}{} {}, , {, # } ; T2 if (!size.IsNarrow() && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADC{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x00a00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADC{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00a00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand); } void Assembler::adcs(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADCS{}{} {}, , # ; T1 if (!size.IsNarrow() && immediate_t32.IsValid() && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADCS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x02b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADCS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADCS{}{} {}, , {, # } ; T2 if (!size.IsNarrow() && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADCS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x00b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADCS{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00b00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADD{}{} , PC, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{} , , # ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADD{} {}, , # ; T2 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADD{}{} , SP, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{}{} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x02a00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADC{} {}, , ; T1 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADC{}{} {}, , {, # } ; T2 if (!size.IsNarrow() && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADC{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x00a00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADC{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00a00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand); } void Assembler::adcs(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADCS{}{} {}, , # ; T1 if (!size.IsNarrow() && immediate_t32.IsValid() && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADCS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x02b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADCS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADCS{}{} {}, , {, # } ; T2 if (!size.IsNarrow() && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADCS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x00b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADCS{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00b00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADD{}{} , PC, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{} , , # ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADD{} {}, , # ; T2 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADD{}{} , SP, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{}{} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , ; T1 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADC{}{} {}, , {, # } ; T2 if (!size.IsNarrow() && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADC{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x00a00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADC{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00a00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand); } void Assembler::adcs(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADCS{}{} {}, , # ; T1 if (!size.IsNarrow() && immediate_t32.IsValid() && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADCS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x02b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADCS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADCS{}{} {}, , {, # } ; T2 if (!size.IsNarrow() && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADCS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x00b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADCS{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00b00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADD{}{} , PC, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{} , , # ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADD{} {}, , # ; T2 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADD{}{} , SP, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{}{} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , {, # } ; T2 if (!size.IsNarrow() && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADC{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x00a00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADC{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00a00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand); } void Assembler::adcs(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADCS{}{} {}, , # ; T1 if (!size.IsNarrow() && immediate_t32.IsValid() && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADCS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x02b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADCS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADCS{}{} {}, , {, # } ; T2 if (!size.IsNarrow() && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADCS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x00b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADCS{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00b00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADD{}{} , PC, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{} , , # ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADD{} {}, , # ; T2 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADD{}{} , SP, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{}{} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x00a00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADC{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00a00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand); } void Assembler::adcs(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADCS{}{} {}, , # ; T1 if (!size.IsNarrow() && immediate_t32.IsValid() && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADCS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x02b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADCS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADCS{}{} {}, , {, # } ; T2 if (!size.IsNarrow() && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADCS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x00b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADCS{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00b00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADD{}{} , PC, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{} , , # ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADD{} {}, , # ; T2 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADD{}{} , SP, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{}{} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00a00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand); } void Assembler::adcs(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADCS{}{} {}, , # ; T1 if (!size.IsNarrow() && immediate_t32.IsValid() && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADCS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x02b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADCS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADCS{}{} {}, , {, # } ; T2 if (!size.IsNarrow() && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADCS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x00b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADCS{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00b00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADD{}{} , PC, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{} , , # ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADD{} {}, , # ; T2 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADD{}{} , SP, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{}{} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , # ; T1 if (!size.IsNarrow() && immediate_t32.IsValid() && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADCS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x02b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADCS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADCS{}{} {}, , {, # } ; T2 if (!size.IsNarrow() && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADCS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x00b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADCS{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00b00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADD{}{} , PC, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{} , , # ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADD{} {}, , # ; T2 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADD{}{} , SP, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{}{} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x02b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADCS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADCS{}{} {}, , {, # } ; T2 if (!size.IsNarrow() && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADCS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x00b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADCS{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00b00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADD{}{} , PC, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{} , , # ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADD{} {}, , # ; T2 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADD{}{} , SP, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{}{} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADCS{}{} {}, , {, # } ; T2 if (!size.IsNarrow() && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADCS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x00b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADCS{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00b00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADD{}{} , PC, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{} , , # ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADD{} {}, , # ; T2 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADD{}{} , SP, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{}{} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , {, # } ; T2 if (!size.IsNarrow() && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADCS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x00b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADCS{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00b00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADD{}{} , PC, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{} , , # ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADD{} {}, , # ; T2 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADD{}{} , SP, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{}{} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x00b00000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADCS{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00b00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADD{}{} , PC, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{} , , # ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADD{} {}, , # ; T2 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADD{}{} , SP, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{}{} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00b00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADD{}{} , PC, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{} , , # ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADD{} {}, , # ; T2 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADD{}{} , SP, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{}{} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} , PC, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{} , , # ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADD{} {}, , # ; T2 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADD{}{} , SP, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{}{} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} , , # ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADD{} {}, , # ; T2 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADD{}{} , SP, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{}{} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , # ; T2 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADD{}{} , SP, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{}{} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} , SP, # ; T1 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_); AdvanceIT(); return; } // ADD{}{} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {SP}, SP, # ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) && ((imm % 4) == 0)) { uint32_t imm_ = imm >> 2; EmitT32_16(0xb000 | imm_); AdvanceIT(); return; } // ADD{}{} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} , PC, # ; T3 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) { EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , # ; T4 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADD{}{} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, SP, # ; T4 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADD{}{} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} , PC, # ; A1 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && ((rn.GetCode() & 0xd) != 0xd)) { EmitA32(0x02800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADD{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x028d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADD{} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} , , ; T1 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } // ADD{}{} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , ; T2 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } // ADD{}{} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, SP, ; T1 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) && ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) || AllowUnpredictable())) { EmitT32_16(0x4468 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4)); AdvanceIT(); return; } // ADD{}{} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {SP}, SP, ; T2 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) { EmitT32_16(0x4485 | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADD{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADD{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADD{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00800000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADD{}{} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, SP, {, # } ; A1 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) { uint32_t amount_ = amount % 32; EmitA32(0x008d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } } } if (operand.IsRegisterShiftedRegister()) { Register rm = operand.GetBaseRegister(); Shift shift = operand.GetShift(); if (IsUsingA32()) { // ADD{}{} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , , ; A1 if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) || AllowUnpredictable())) { EmitA32(0x00800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) | (operand.GetShiftRegister().GetCode() << 8)); return; } } } Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand); } void Assembler::add(Condition cond, Register rd, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { // ADD{} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} , # ; T2 if (InITBlock() && rd.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } } } if (operand.IsPlainRegister()) { Register rm = operand.GetBaseRegister(); if (IsUsingT32()) { // ADD{} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} , ; T2 if (InITBlock() && !rm.Is(sp) && (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) && (!rd.IsPC() || !rm.IsPC())) || AllowUnpredictable())) { EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3)); AdvanceIT(); return; } } } Delegate(kAdd, &Assembler::add, cond, rd, operand); } void Assembler::adds(Condition cond, EncodingSize size, Register rd, Register rn, const Operand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); if (operand.IsImmediate()) { uint32_t imm = operand.GetImmediate(); if (IsUsingT32()) { ImmediateT32 immediate_t32(imm); // ADDS{} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} , , # ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && (imm <= 7)) { EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6)); AdvanceIT(); return; } // ADDS{} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , # ; T2 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() && (imm <= 255)) { EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm); AdvanceIT(); return; } // ADDS{}{} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , # ; T3 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) && !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) { EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } // ADDS{}{} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, SP, # ; T3 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() && !rd.Is(pc)) { EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) | (immediate_t32.GetEncodingValue() & 0xff) | ((immediate_t32.GetEncodingValue() & 0x700) << 4) | ((immediate_t32.GetEncodingValue() & 0x800) << 15)); AdvanceIT(); return; } } else { ImmediateA32 immediate_a32(imm); // ADDS{}{} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , # ; A1 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) { EmitA32(0x02900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | immediate_a32.GetEncodingValue()); return; } // ADDS{}{} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, SP, # ; A1 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) { EmitA32(0x029d0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | immediate_a32.GetEncodingValue()); return; } } } if (operand.IsImmediateShiftedRegister()) { Register rm = operand.GetBaseRegister(); if (operand.IsPlainRegister()) { if (IsUsingT32()) { // ADDS{} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , ; T1 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() && rm.IsLow()) { EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) | (rm.GetCode() << 6)); AdvanceIT(); return; } } } Shift shift = operand.GetShift(); uint32_t amount = operand.GetShiftAmount(); if (IsUsingT32()) { // ADDS{}{} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , {, # } ; T3 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) && !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } // ADDS{}{} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, SP, {, # } ; T3 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) && !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) { uint32_t amount_ = amount % 32; EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() | (operand.GetTypeEncodingValue() << 4) | ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10)); AdvanceIT(); return; } } else { // ADDS{}{} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, , {, # } ; A1 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) { uint32_t amount_ = amount % 32; EmitA32(0x00900000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() | (operand.GetTypeEncodingValue() << 5) | (amount_ << 7)); return; } // ADDS{}{} {}, SP,
} {}, SP,