1089 branch_reg((Register)0b11111, opc); \
1090 }
1091
1092 INSN(eret, 0b0100);
1093 INSN(drps, 0b0101);
1094
1095 #undef INSN
1096
1097 // Load/store exclusive
1098 enum operand_size { byte, halfword, word, xword };
1099
1100 void load_store_exclusive(Register Rs, Register Rt1, Register Rt2,
1101 Register Rn, enum operand_size sz, int op, int o0) {
1102 starti;
1103 f(sz, 31, 30), f(0b001000, 29, 24), f(op, 23, 21);
1104 rf(Rs, 16), f(o0, 15), rf(Rt2, 10), rf(Rn, 5), rf(Rt1, 0);
1105 }
1106
1107 #define INSN4(NAME, sz, op, o0) /* Four registers */ \
1108 void NAME(Register Rs, Register Rt1, Register Rt2, Register Rn) { \
1109 load_store_exclusive(Rs, Rt1, Rt2, Rn, sz, op, o0); \
1110 }
1111
1112 #define INSN3(NAME, sz, op, o0) /* Three registers */ \
1113 void NAME(Register Rs, Register Rt, Register Rn) { \
1114 load_store_exclusive(Rs, Rt, (Register)0b11111, Rn, sz, op, o0); \
1115 }
1116
1117 #define INSN2(NAME, sz, op, o0) /* Two registers */ \
1118 void NAME(Register Rt, Register Rn) { \
1119 load_store_exclusive((Register)0b11111, Rt, (Register)0b11111, \
1120 Rn, sz, op, o0); \
1121 }
1122
1123 #define INSN_FOO(NAME, sz, op, o0) /* Three registers, encoded differently */ \
1124 void NAME(Register Rt1, Register Rt2, Register Rn) { \
1125 load_store_exclusive((Register)0b11111, Rt1, Rt2, Rn, sz, op, o0); \
1126 }
1127
1128 // bytes
1129 INSN3(stxrb, byte, 0b000, 0);
1130 INSN3(stlxrb, byte, 0b000, 1);
1131 INSN2(ldxrb, byte, 0b010, 0);
1132 INSN2(ldaxrb, byte, 0b010, 1);
1133 INSN2(stlrb, byte, 0b100, 1);
|
1089 branch_reg((Register)0b11111, opc); \
1090 }
1091
1092 INSN(eret, 0b0100);
1093 INSN(drps, 0b0101);
1094
1095 #undef INSN
1096
1097 // Load/store exclusive
1098 enum operand_size { byte, halfword, word, xword };
1099
1100 void load_store_exclusive(Register Rs, Register Rt1, Register Rt2,
1101 Register Rn, enum operand_size sz, int op, int o0) {
1102 starti;
1103 f(sz, 31, 30), f(0b001000, 29, 24), f(op, 23, 21);
1104 rf(Rs, 16), f(o0, 15), rf(Rt2, 10), rf(Rn, 5), rf(Rt1, 0);
1105 }
1106
1107 #define INSN4(NAME, sz, op, o0) /* Four registers */ \
1108 void NAME(Register Rs, Register Rt1, Register Rt2, Register Rn) { \
1109 assert(Rs != Rn, "unpredictable instruction"); \
1110 load_store_exclusive(Rs, Rt1, Rt2, Rn, sz, op, o0); \
1111 }
1112
1113 #define INSN3(NAME, sz, op, o0) /* Three registers */ \
1114 void NAME(Register Rs, Register Rt, Register Rn) { \
1115 assert(Rs != Rn, "unpredictable instruction"); \
1116 load_store_exclusive(Rs, Rt, (Register)0b11111, Rn, sz, op, o0); \
1117 }
1118
1119 #define INSN2(NAME, sz, op, o0) /* Two registers */ \
1120 void NAME(Register Rt, Register Rn) { \
1121 load_store_exclusive((Register)0b11111, Rt, (Register)0b11111, \
1122 Rn, sz, op, o0); \
1123 }
1124
1125 #define INSN_FOO(NAME, sz, op, o0) /* Three registers, encoded differently */ \
1126 void NAME(Register Rt1, Register Rt2, Register Rn) { \
1127 load_store_exclusive((Register)0b11111, Rt1, Rt2, Rn, sz, op, o0); \
1128 }
1129
1130 // bytes
1131 INSN3(stxrb, byte, 0b000, 0);
1132 INSN3(stlxrb, byte, 0b000, 1);
1133 INSN2(ldxrb, byte, 0b010, 0);
1134 INSN2(ldaxrb, byte, 0b010, 1);
1135 INSN2(stlrb, byte, 0b100, 1);
|