857
858 #define INSN(NAME, decode, s_flg) \
859 inline void NAME(Register Rd, Register Rn, unsigned imm, Condition cond = C_DFLT) {\
860 bool status = imm_instr(decode, Rd, Rn, imm, cond, s_flg); \
861 assert(status, "invalid imm"); \
862 }
863 INSN(andr, 0b0000, 0);
864 INSN(eor, 0b0001, 0);
865 INSN(orr, 0b1100, 0);
866 INSN(bic, 0b1110, 0);
867
868 INSN(ands, 0b0000, 1);
869 INSN(eors, 0b0001, 1);
870 INSN(orrs, 0b1100, 1);
871 INSN(bics, 0b1110, 1);
872 //NOTE: arithmetic immediate instructions are defined below to allow dispatch.
873 #undef INSN
874 protected:
875 // Mov data to destination register in the shortest number of instructions
876 // possible.
877 void mov_immediate(Register dst, u_int32_t imm32, Condition cond, bool s);
878 // Mov data to destination register but always emit enough instructions that would
879 // permit any 32-bit constant to be loaded. (Allow for rewriting later).
880 void mov_immediate32(Register dst, u_int32_t imm32, Condition cond, bool s);
881
882 void add_sub_imm(int decode, Register Rd, Register Rn, int imm,
883 Condition cond, bool s);
884
885 public:
886 #define INSN(NAME, decode, s_flg) \
887 inline void NAME(Register Rd, Register Rn, int imm, Condition cond = C_DFLT) { \
888 add_sub_imm(decode, Rd, Rn, imm, cond, s_flg); \
889 } \
890 inline void NAME(Register Rd, Register Rn, unsigned imm, \
891 Condition cond = C_DFLT) { \
892 add_sub_imm(decode, Rd, Rn, imm, cond, s_flg); \
893 } \
894 inline void NAME(Register Rd, Register Rn, long imm, Condition cond = C_DFLT) { \
895 add_sub_imm(decode, Rd, Rn, imm, cond, s_flg); \
896 } \
897 inline void NAME(Register Rd, Register Rn, unsigned long imm, \
898 Condition cond = C_DFLT) { \
899 add_sub_imm(decode, Rd, Rn, imm, cond, s_flg); \
900 } \
1193 // LDR, LDRB, STR, STRB
1194 return uabs(offset) < (1 << 12);
1195 case 0b000:
1196 //LDRD, LDRH, LDRSB, LDRSH, STRH, STRD
1197 return uabs(offset) < (1 << 8);
1198 default:
1199 ShouldNotReachHere();
1200 }
1201 return false;
1202 }
1203
1204
1205
1206 #define INSN_INT(NAME, op, op2, a, b, isload) \
1207 void NAME(Register Rt, address dest, Condition cond = C_DFLT) { \
1208 if(encodeable(op, dest)) { /* Plan A */ \
1209 long offset = dest - pc(); \
1210 NAME(Rt, Address(r15_pc, offset), cond); \
1211 } else if(isload){ /* Plan B */ \
1212 /* TODO check we don't have to relocate this*/ \
1213 mov_immediate(Rt, (u_int32_t)dest, cond, false); \
1214 NAME(Rt, Address(Rt, 0), cond); \
1215 } else { /* There is no plan C */ \
1216 ShouldNotReachHere(); \
1217 } \
1218 } \
1219 void NAME(Register Rt, address dest, relocInfo::relocType rtype, \
1220 Condition cond = C_DFLT) { \
1221 guarantee(rtype == relocInfo::internal_word_type, \
1222 "only internal_word_type relocs make sense here"); \
1223 NAME(Rt, InternalAddress(dest), cond); \
1224 } \
1225 void NAME(Register Rt, Label &L, Condition cond = C_DFLT) { \
1226 wrap_label(Rt, L, cond, &Assembler::NAME); \
1227 }
1228
1229 #define INSN(NAME, op, op2, a, b, isload) \
1230 void NAME(Register Rt, const Address &adr, Condition cond = C_DFLT) { \
1231 load_store_instr(Rt, adr, op, op2, a, b, cond); \
1232 } \
1233 INSN_INT(NAME, op, op2, a, b, isload);
1579
1580
1581 // Unconditional Instructions
1582 enum barrier {OSHST = 0b0010, OSH,
1583 NSHST = 0b0110, NSH,
1584 ISHST = 0b1010, ISH,
1585 ST = 0b1110, SY};
1586
1587 void sync_instr(int decode, enum barrier option) {
1588 starti;
1589 f(0b11110, 31, 27), f(0b1010111, 26, 20), f(0b111111110000, 19, 8);
1590 f(decode, 7, 4), f(option, 3, 0);
1591 }
1592 void clrex() {
1593 sync_instr(0b0001, SY);
1594 }
1595 void dsb(enum barrier option) {
1596 sync_instr(0b0100, option);
1597 }
1598 void dmb(enum barrier option) {
1599 sync_instr(0b0100, option);
1600 }
1601 void bkpt();
1602 void isb() {
1603 sync_instr(0b0110, SY);
1604 }
1605
1606 // And the relevant instructions for ARMv6.
1607
1608 // MCR<c> <coproc>, <opc1>, <Rt>, <CRn>, <CRm>{, <opc2>}
1609 void mcr(int cpc_dex, int opc1, Register Rt, int cpc_reg_dex1,
1610 int cpc_reg_dex2, int opc2, Condition cond = C_DFLT) {
1611 starti;
1612 f(cond, 31, 28), f(0b1110, 27, 24), f(opc1, 23, 21), f(0, 20);
1613 f(cpc_reg_dex1, 19, 16), rf(Rt, 12), f(cpc_dex, 11, 8);
1614 f(opc2, 7, 5), f(1, 4), f(cpc_reg_dex2, 3, 0);
1615 }
1616
1617 // These instructions do not read the value of the register passed,
1618 // can be any. Chosen r0.
1619 void cp15dmb(Condition cond = C_DFLT) {
|
857
858 #define INSN(NAME, decode, s_flg) \
859 inline void NAME(Register Rd, Register Rn, unsigned imm, Condition cond = C_DFLT) {\
860 bool status = imm_instr(decode, Rd, Rn, imm, cond, s_flg); \
861 assert(status, "invalid imm"); \
862 }
863 INSN(andr, 0b0000, 0);
864 INSN(eor, 0b0001, 0);
865 INSN(orr, 0b1100, 0);
866 INSN(bic, 0b1110, 0);
867
868 INSN(ands, 0b0000, 1);
869 INSN(eors, 0b0001, 1);
870 INSN(orrs, 0b1100, 1);
871 INSN(bics, 0b1110, 1);
872 //NOTE: arithmetic immediate instructions are defined below to allow dispatch.
873 #undef INSN
874 protected:
875 // Mov data to destination register in the shortest number of instructions
876 // possible.
877 void mov_immediate(Register dst, uint32_t imm32, Condition cond, bool s);
878 // Mov data to destination register but always emit enough instructions that would
879 // permit any 32-bit constant to be loaded. (Allow for rewriting later).
880 void mov_immediate32(Register dst, uint32_t imm32, Condition cond, bool s);
881
882 void add_sub_imm(int decode, Register Rd, Register Rn, int imm,
883 Condition cond, bool s);
884
885 public:
886 #define INSN(NAME, decode, s_flg) \
887 inline void NAME(Register Rd, Register Rn, int imm, Condition cond = C_DFLT) { \
888 add_sub_imm(decode, Rd, Rn, imm, cond, s_flg); \
889 } \
890 inline void NAME(Register Rd, Register Rn, unsigned imm, \
891 Condition cond = C_DFLT) { \
892 add_sub_imm(decode, Rd, Rn, imm, cond, s_flg); \
893 } \
894 inline void NAME(Register Rd, Register Rn, long imm, Condition cond = C_DFLT) { \
895 add_sub_imm(decode, Rd, Rn, imm, cond, s_flg); \
896 } \
897 inline void NAME(Register Rd, Register Rn, unsigned long imm, \
898 Condition cond = C_DFLT) { \
899 add_sub_imm(decode, Rd, Rn, imm, cond, s_flg); \
900 } \
1193 // LDR, LDRB, STR, STRB
1194 return uabs(offset) < (1 << 12);
1195 case 0b000:
1196 //LDRD, LDRH, LDRSB, LDRSH, STRH, STRD
1197 return uabs(offset) < (1 << 8);
1198 default:
1199 ShouldNotReachHere();
1200 }
1201 return false;
1202 }
1203
1204
1205
1206 #define INSN_INT(NAME, op, op2, a, b, isload) \
1207 void NAME(Register Rt, address dest, Condition cond = C_DFLT) { \
1208 if(encodeable(op, dest)) { /* Plan A */ \
1209 long offset = dest - pc(); \
1210 NAME(Rt, Address(r15_pc, offset), cond); \
1211 } else if(isload){ /* Plan B */ \
1212 /* TODO check we don't have to relocate this*/ \
1213 mov_immediate(Rt, (uint32_t)dest, cond, false); \
1214 NAME(Rt, Address(Rt, 0), cond); \
1215 } else { /* There is no plan C */ \
1216 ShouldNotReachHere(); \
1217 } \
1218 } \
1219 void NAME(Register Rt, address dest, relocInfo::relocType rtype, \
1220 Condition cond = C_DFLT) { \
1221 guarantee(rtype == relocInfo::internal_word_type, \
1222 "only internal_word_type relocs make sense here"); \
1223 NAME(Rt, InternalAddress(dest), cond); \
1224 } \
1225 void NAME(Register Rt, Label &L, Condition cond = C_DFLT) { \
1226 wrap_label(Rt, L, cond, &Assembler::NAME); \
1227 }
1228
1229 #define INSN(NAME, op, op2, a, b, isload) \
1230 void NAME(Register Rt, const Address &adr, Condition cond = C_DFLT) { \
1231 load_store_instr(Rt, adr, op, op2, a, b, cond); \
1232 } \
1233 INSN_INT(NAME, op, op2, a, b, isload);
1579
1580
1581 // Unconditional Instructions
1582 enum barrier {OSHST = 0b0010, OSH,
1583 NSHST = 0b0110, NSH,
1584 ISHST = 0b1010, ISH,
1585 ST = 0b1110, SY};
1586
1587 void sync_instr(int decode, enum barrier option) {
1588 starti;
1589 f(0b11110, 31, 27), f(0b1010111, 26, 20), f(0b111111110000, 19, 8);
1590 f(decode, 7, 4), f(option, 3, 0);
1591 }
1592 void clrex() {
1593 sync_instr(0b0001, SY);
1594 }
1595 void dsb(enum barrier option) {
1596 sync_instr(0b0100, option);
1597 }
1598 void dmb(enum barrier option) {
1599 sync_instr(0b0101, option);
1600 }
1601 void bkpt();
1602 void isb() {
1603 sync_instr(0b0110, SY);
1604 }
1605
1606 // And the relevant instructions for ARMv6.
1607
1608 // MCR<c> <coproc>, <opc1>, <Rt>, <CRn>, <CRm>{, <opc2>}
1609 void mcr(int cpc_dex, int opc1, Register Rt, int cpc_reg_dex1,
1610 int cpc_reg_dex2, int opc2, Condition cond = C_DFLT) {
1611 starti;
1612 f(cond, 31, 28), f(0b1110, 27, 24), f(opc1, 23, 21), f(0, 20);
1613 f(cpc_reg_dex1, 19, 16), rf(Rt, 12), f(cpc_dex, 11, 8);
1614 f(opc2, 7, 5), f(1, 4), f(cpc_reg_dex2, 3, 0);
1615 }
1616
1617 // These instructions do not read the value of the register passed,
1618 // can be any. Chosen r0.
1619 void cp15dmb(Condition cond = C_DFLT) {
|