955 }
956
957 #define INSN(NAME, opc, op2, LL) \
958 void NAME(unsigned imm) { \
959 generate_exception(opc, op2, LL, imm); \
960 }
961
962 INSN(svc, 0b000, 0, 0b01);
963 INSN(hvc, 0b000, 0, 0b10);
964 INSN(smc, 0b000, 0, 0b11);
965 INSN(brk, 0b001, 0, 0b00);
966 INSN(hlt, 0b010, 0, 0b00);
967 INSN(dpcs1, 0b101, 0, 0b01);
968 INSN(dpcs2, 0b101, 0, 0b10);
969 INSN(dpcs3, 0b101, 0, 0b11);
970
971 #undef INSN
972
973 // System
974 void system(int op0, int op1, int CRn, int CRm, int op2,
975 Register rt = (Register)0b11111)
976 {
977 starti;
978 f(0b11010101000, 31, 21);
979 f(op0, 20, 19);
980 f(op1, 18, 16);
981 f(CRn, 15, 12);
982 f(CRm, 11, 8);
983 f(op2, 7, 5);
984 rf(rt, 0);
985 }
986
987 void hint(int imm) {
988 system(0b00, 0b011, 0b0010, imm, 0b000);
989 }
990
991 void nop() {
992 hint(0);
993 }
994 // we only provide mrs and msr for the special purpose system
995 // registers where op1 (instr[20:19]) == 11 and, (currently) only
1065 f(0b11111000000, 20, 10);
1066 rf(R, 5);
1067 f(0b00000, 4, 0);
1068 }
1069
1070 #define INSN(NAME, opc) \
1071 void NAME(Register R) { \
1072 branch_reg(R, opc); \
1073 }
1074
1075 INSN(br, 0b0000);
1076 INSN(blr, 0b0001);
1077 INSN(ret, 0b0010);
1078
1079 void ret(void *p); // This forces a compile-time error for ret(0)
1080
1081 #undef INSN
1082
1083 #define INSN(NAME, opc) \
1084 void NAME() { \
1085 branch_reg((Register)0b11111, opc); \
1086 }
1087
1088 INSN(eret, 0b0100);
1089 INSN(drps, 0b0101);
1090
1091 #undef INSN
1092
1093 // Load/store exclusive
1094 enum operand_size { byte, halfword, word, xword };
1095
1096 void load_store_exclusive(Register Rs, Register Rt1, Register Rt2,
1097 Register Rn, enum operand_size sz, int op, int o0) {
1098 starti;
1099 f(sz, 31, 30), f(0b001000, 29, 24), f(op, 23, 21);
1100 rf(Rs, 16), f(o0, 15), rf(Rt2, 10), rf(Rn, 5), rf(Rt1, 0);
1101 }
1102
1103 #define INSN4(NAME, sz, op, o0) /* Four registers */ \
1104 void NAME(Register Rs, Register Rt1, Register Rt2, Register Rn) { \
1105 guarantee(Rs != Rn && Rs != Rt1 && Rs != Rt2, "unpredictable instruction"); \
1106 load_store_exclusive(Rs, Rt1, Rt2, Rn, sz, op, o0); \
1107 }
1108
1109 #define INSN3(NAME, sz, op, o0) /* Three registers */ \
1110 void NAME(Register Rs, Register Rt, Register Rn) { \
1111 guarantee(Rs != Rn && Rs != Rt, "unpredictable instruction"); \
1112 load_store_exclusive(Rs, Rt, (Register)0b11111, Rn, sz, op, o0); \
1113 }
1114
1115 #define INSN2(NAME, sz, op, o0) /* Two registers */ \
1116 void NAME(Register Rt, Register Rn) { \
1117 load_store_exclusive((Register)0b11111, Rt, (Register)0b11111, \
1118 Rn, sz, op, o0); \
1119 }
1120
1121 #define INSN_FOO(NAME, sz, op, o0) /* Three registers, encoded differently */ \
1122 void NAME(Register Rt1, Register Rt2, Register Rn) { \
1123 guarantee(Rt1 != Rt2, "unpredictable instruction"); \
1124 load_store_exclusive((Register)0b11111, Rt1, Rt2, Rn, sz, op, o0); \
1125 }
1126
1127 // bytes
1128 INSN3(stxrb, byte, 0b000, 0);
1129 INSN3(stlxrb, byte, 0b000, 1);
1130 INSN2(ldxrb, byte, 0b010, 0);
1131 INSN2(ldaxrb, byte, 0b010, 1);
1132 INSN2(stlrb, byte, 0b100, 1);
1133 INSN2(ldarb, byte, 0b110, 1);
1134
1135 // halfwords
1136 INSN3(stxrh, halfword, 0b000, 0);
1137 INSN3(stlxrh, halfword, 0b000, 1);
1138 INSN2(ldxrh, halfword, 0b010, 0);
1139 INSN2(ldaxrh, halfword, 0b010, 1);
1140 INSN2(stlrh, halfword, 0b100, 1);
1141 INSN2(ldarh, halfword, 0b110, 1);
1142
1143 // words
1144 INSN3(stxrw, word, 0b000, 0);
1151 INSN_FOO(ldaxpw, word, 0b011, 1);
1152 INSN2(stlrw, word, 0b100, 1);
1153 INSN2(ldarw, word, 0b110, 1);
1154
1155 // xwords
1156 INSN3(stxr, xword, 0b000, 0);
1157 INSN3(stlxr, xword, 0b000, 1);
1158 INSN4(stxp, xword, 0b001, 0);
1159 INSN4(stlxp, xword, 0b001, 1);
1160 INSN2(ldxr, xword, 0b010, 0);
1161 INSN2(ldaxr, xword, 0b010, 1);
1162 INSN_FOO(ldxp, xword, 0b011, 0);
1163 INSN_FOO(ldaxp, xword, 0b011, 1);
1164 INSN2(stlr, xword, 0b100, 1);
1165 INSN2(ldar, xword, 0b110, 1);
1166
1167 #undef INSN2
1168 #undef INSN3
1169 #undef INSN4
1170 #undef INSN_FOO
1171
1172 // Load register (literal)
1173 #define INSN(NAME, opc, V) \
1174 void NAME(Register Rt, address dest) { \
1175 long offset = (dest - pc()) >> 2; \
1176 starti; \
1177 f(opc, 31, 30), f(0b011, 29, 27), f(V, 26), f(0b00, 25, 24), \
1178 sf(offset, 23, 5); \
1179 rf(Rt, 0); \
1180 } \
1181 void NAME(Register Rt, address dest, relocInfo::relocType rtype) { \
1182 InstructionMark im(this); \
1183 guarantee(rtype == relocInfo::internal_word_type, \
1184 "only internal_word_type relocs make sense here"); \
1185 code_section()->relocate(inst_mark(), InternalAddress(dest).rspec()); \
1186 NAME(Rt, dest); \
1187 } \
1188 void NAME(Register Rt, Label &L) { \
1189 wrap_label(Rt, L, &Assembler::NAME); \
1190 }
|
955 }
956
957 #define INSN(NAME, opc, op2, LL) \
958 void NAME(unsigned imm) { \
959 generate_exception(opc, op2, LL, imm); \
960 }
961
962 INSN(svc, 0b000, 0, 0b01);
963 INSN(hvc, 0b000, 0, 0b10);
964 INSN(smc, 0b000, 0, 0b11);
965 INSN(brk, 0b001, 0, 0b00);
966 INSN(hlt, 0b010, 0, 0b00);
967 INSN(dpcs1, 0b101, 0, 0b01);
968 INSN(dpcs2, 0b101, 0, 0b10);
969 INSN(dpcs3, 0b101, 0, 0b11);
970
971 #undef INSN
972
973 // System
974 void system(int op0, int op1, int CRn, int CRm, int op2,
975 Register rt = dummy_reg)
976 {
977 starti;
978 f(0b11010101000, 31, 21);
979 f(op0, 20, 19);
980 f(op1, 18, 16);
981 f(CRn, 15, 12);
982 f(CRm, 11, 8);
983 f(op2, 7, 5);
984 rf(rt, 0);
985 }
986
987 void hint(int imm) {
988 system(0b00, 0b011, 0b0010, imm, 0b000);
989 }
990
991 void nop() {
992 hint(0);
993 }
994 // we only provide mrs and msr for the special purpose system
995 // registers where op1 (instr[20:19]) == 11 and, (currently) only
1065 f(0b11111000000, 20, 10);
1066 rf(R, 5);
1067 f(0b00000, 4, 0);
1068 }
1069
1070 #define INSN(NAME, opc) \
1071 void NAME(Register R) { \
1072 branch_reg(R, opc); \
1073 }
1074
1075 INSN(br, 0b0000);
1076 INSN(blr, 0b0001);
1077 INSN(ret, 0b0010);
1078
1079 void ret(void *p); // This forces a compile-time error for ret(0)
1080
1081 #undef INSN
1082
1083 #define INSN(NAME, opc) \
1084 void NAME() { \
1085 branch_reg(dummy_reg, opc); \
1086 }
1087
1088 INSN(eret, 0b0100);
1089 INSN(drps, 0b0101);
1090
1091 #undef INSN
1092
1093 // Load/store exclusive
1094 enum operand_size { byte, halfword, word, xword };
1095
1096 void load_store_exclusive(Register Rs, Register Rt1, Register Rt2,
1097 Register Rn, enum operand_size sz, int op, bool ordered) {
1098 starti;
1099 f(sz, 31, 30), f(0b001000, 29, 24), f(op, 23, 21);
1100 rf(Rs, 16), f(ordered, 15), rf(Rt2, 10), rf(Rn, 5), rf(Rt1, 0);
1101 }
1102
1103 void load_exclusive(Register dst, Register addr,
1104 enum operand_size sz, bool ordered) {
1105 load_store_exclusive(dummy_reg, dst, dummy_reg, addr,
1106 sz, 0b010, ordered);
1107 }
1108
1109 void store_exclusive(Register status, Register new_val, Register addr,
1110 enum operand_size sz, bool ordered) {
1111 load_store_exclusive(status, new_val, dummy_reg, addr,
1112 sz, 0b000, ordered);
1113 }
1114
1115 #define INSN4(NAME, sz, op, o0) /* Four registers */ \
1116 void NAME(Register Rs, Register Rt1, Register Rt2, Register Rn) { \
1117 guarantee(Rs != Rn && Rs != Rt1 && Rs != Rt2, "unpredictable instruction"); \
1118 load_store_exclusive(Rs, Rt1, Rt2, Rn, sz, op, o0); \
1119 }
1120
1121 #define INSN3(NAME, sz, op, o0) /* Three registers */ \
1122 void NAME(Register Rs, Register Rt, Register Rn) { \
1123 guarantee(Rs != Rn && Rs != Rt, "unpredictable instruction"); \
1124 load_store_exclusive(Rs, Rt, dummy_reg, Rn, sz, op, o0); \
1125 }
1126
1127 #define INSN2(NAME, sz, op, o0) /* Two registers */ \
1128 void NAME(Register Rt, Register Rn) { \
1129 load_store_exclusive(dummy_reg, Rt, dummy_reg, \
1130 Rn, sz, op, o0); \
1131 }
1132
1133 #define INSN_FOO(NAME, sz, op, o0) /* Three registers, encoded differently */ \
1134 void NAME(Register Rt1, Register Rt2, Register Rn) { \
1135 guarantee(Rt1 != Rt2, "unpredictable instruction"); \
1136 load_store_exclusive(dummy_reg, Rt1, Rt2, Rn, sz, op, o0); \
1137 }
1138
1139 // bytes
1140 INSN3(stxrb, byte, 0b000, 0);
1141 INSN3(stlxrb, byte, 0b000, 1);
1142 INSN2(ldxrb, byte, 0b010, 0);
1143 INSN2(ldaxrb, byte, 0b010, 1);
1144 INSN2(stlrb, byte, 0b100, 1);
1145 INSN2(ldarb, byte, 0b110, 1);
1146
1147 // halfwords
1148 INSN3(stxrh, halfword, 0b000, 0);
1149 INSN3(stlxrh, halfword, 0b000, 1);
1150 INSN2(ldxrh, halfword, 0b010, 0);
1151 INSN2(ldaxrh, halfword, 0b010, 1);
1152 INSN2(stlrh, halfword, 0b100, 1);
1153 INSN2(ldarh, halfword, 0b110, 1);
1154
1155 // words
1156 INSN3(stxrw, word, 0b000, 0);
1163 INSN_FOO(ldaxpw, word, 0b011, 1);
1164 INSN2(stlrw, word, 0b100, 1);
1165 INSN2(ldarw, word, 0b110, 1);
1166
1167 // xwords
1168 INSN3(stxr, xword, 0b000, 0);
1169 INSN3(stlxr, xword, 0b000, 1);
1170 INSN4(stxp, xword, 0b001, 0);
1171 INSN4(stlxp, xword, 0b001, 1);
1172 INSN2(ldxr, xword, 0b010, 0);
1173 INSN2(ldaxr, xword, 0b010, 1);
1174 INSN_FOO(ldxp, xword, 0b011, 0);
1175 INSN_FOO(ldaxp, xword, 0b011, 1);
1176 INSN2(stlr, xword, 0b100, 1);
1177 INSN2(ldar, xword, 0b110, 1);
1178
1179 #undef INSN2
1180 #undef INSN3
1181 #undef INSN4
1182 #undef INSN_FOO
1183
1184 // 8.1 Compare and swap extensions
1185 void lse_cas(Register Rs, Register Rt, Register Rn,
1186 enum operand_size sz, bool a, bool r, bool not_pair) {
1187 starti;
1188 if (! not_pair) { // Pair
1189 assert(sz == word || sz == xword, "invalid size");
1190 /* The size bit is in bit 30, not 31 */
1191 sz = (operand_size)(sz == word ? 0b00:0b01);
1192 }
1193 f(sz, 31, 30), f(0b001000, 29, 24), f(1, 23), f(a, 22), f(1, 21);
1194 rf(Rs, 16), f(r, 15), f(0b11111, 14, 10), rf(Rn, 5), rf(Rt, 0);
1195 }
1196
1197 // CAS
1198 #define INSN(NAME, a, r) \
1199 void NAME(operand_size sz, Register Rs, Register Rt, Register Rn) { \
1200 assert(Rs != Rn && Rs != Rt, "unpredictable instruction"); \
1201 lse_cas(Rs, Rt, Rn, sz, a, r, true); \
1202 }
1203 INSN(cas, false, false)
1204 INSN(casa, true, false)
1205 INSN(casl, false, true)
1206 INSN(casal, true, true)
1207 #undef INSN
1208
1209 // CASP
1210 #define INSN(NAME, a, r) \
1211 void NAME(operand_size sz, Register Rs, Register Rs1, \
1212 Register Rt, Register Rt1, Register Rn) { \
1213 assert((Rs->encoding() & 1) == 0 && (Rt->encoding() & 1) == 0 && \
1214 Rs->successor() == Rs1 && Rt->successor() == Rt1 && \
1215 Rs != Rn && Rs1 != Rn && Rs != Rt, "invalid registers"); \
1216 lse_cas(Rs, Rt, Rn, sz, a, r, false); \
1217 }
1218 INSN(casp, false, false)
1219 INSN(caspa, true, false)
1220 INSN(caspl, false, true)
1221 INSN(caspal, true, true)
1222 #undef INSN
1223
1224 // Load register (literal)
1225 #define INSN(NAME, opc, V) \
1226 void NAME(Register Rt, address dest) { \
1227 long offset = (dest - pc()) >> 2; \
1228 starti; \
1229 f(opc, 31, 30), f(0b011, 29, 27), f(V, 26), f(0b00, 25, 24), \
1230 sf(offset, 23, 5); \
1231 rf(Rt, 0); \
1232 } \
1233 void NAME(Register Rt, address dest, relocInfo::relocType rtype) { \
1234 InstructionMark im(this); \
1235 guarantee(rtype == relocInfo::internal_word_type, \
1236 "only internal_word_type relocs make sense here"); \
1237 code_section()->relocate(inst_mark(), InternalAddress(dest).rspec()); \
1238 NAME(Rt, dest); \
1239 } \
1240 void NAME(Register Rt, Label &L) { \
1241 wrap_label(Rt, L, &Assembler::NAME); \
1242 }
|