summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/ir/ir_emitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/frontend/ir/ir_emitter.cpp')
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp145
1 files changed, 95 insertions, 50 deletions
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index 672836c0b..652f6949e 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -53,6 +53,10 @@ U64 IREmitter::Imm64(u64 value) const {
53 return U64{Value{value}}; 53 return U64{Value{value}};
54} 54}
55 55
56U64 IREmitter::Imm64(s64 value) const {
57 return U64{Value{static_cast<u64>(value)}};
58}
59
56F64 IREmitter::Imm64(f64 value) const { 60F64 IREmitter::Imm64(f64 value) const {
57 return F64{Value{value}}; 61 return F64{Value{value}};
58} 62}
@@ -363,7 +367,7 @@ U1 IREmitter::GetSparseFromOp(const Value& op) {
363} 367}
364 368
365F16F32F64 IREmitter::FPAdd(const F16F32F64& a, const F16F32F64& b, FpControl control) { 369F16F32F64 IREmitter::FPAdd(const F16F32F64& a, const F16F32F64& b, FpControl control) {
366 if (a.Type() != a.Type()) { 370 if (a.Type() != b.Type()) {
367 throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type()); 371 throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type());
368 } 372 }
369 switch (a.Type()) { 373 switch (a.Type()) {
@@ -974,8 +978,15 @@ U32U64 IREmitter::INeg(const U32U64& value) {
974 } 978 }
975} 979}
976 980
977U32 IREmitter::IAbs(const U32& value) { 981U32U64 IREmitter::IAbs(const U32U64& value) {
978 return Inst<U32>(Opcode::IAbs32, value); 982 switch (value.Type()) {
983 case Type::U32:
984 return Inst<U32>(Opcode::IAbs32, value);
985 case Type::U64:
986 return Inst<U64>(Opcode::IAbs64, value);
987 default:
988 ThrowInvalidType(value.Type());
989 }
979} 990}
980 991
981U32U64 IREmitter::ShiftLeftLogical(const U32U64& base, const U32& shift) { 992U32U64 IREmitter::ShiftLeftLogical(const U32U64& base, const U32& shift) {
@@ -1074,8 +1085,25 @@ U1 IREmitter::ILessThan(const U32& lhs, const U32& rhs, bool is_signed) {
1074 return Inst<U1>(is_signed ? Opcode::SLessThan : Opcode::ULessThan, lhs, rhs); 1085 return Inst<U1>(is_signed ? Opcode::SLessThan : Opcode::ULessThan, lhs, rhs);
1075} 1086}
1076 1087
1077U1 IREmitter::IEqual(const U32& lhs, const U32& rhs) { 1088U1 IREmitter::IEqual(const U32U64& lhs, const U32U64& rhs) {
1078 return Inst<U1>(Opcode::IEqual, lhs, rhs); 1089 if (lhs.Type() != rhs.Type()) {
1090 throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type());
1091 }
1092 switch (lhs.Type()) {
1093 case Type::U32:
1094 return Inst<U1>(Opcode::IEqual, lhs, rhs);
1095 case Type::U64: {
1096 // Manually compare the unpacked values
1097 const Value lhs_vector{UnpackUint2x32(lhs)};
1098 const Value rhs_vector{UnpackUint2x32(rhs)};
1099 return LogicalAnd(IEqual(IR::U32{CompositeExtract(lhs_vector, 0)},
1100 IR::U32{CompositeExtract(rhs_vector, 0)}),
1101 IEqual(IR::U32{CompositeExtract(lhs_vector, 1)},
1102 IR::U32{CompositeExtract(rhs_vector, 1)}));
1103 }
1104 default:
1105 ThrowInvalidType(lhs.Type());
1106 }
1079} 1107}
1080 1108
1081U1 IREmitter::ILessThanEqual(const U32& lhs, const U32& rhs, bool is_signed) { 1109U1 IREmitter::ILessThanEqual(const U32& lhs, const U32& rhs, bool is_signed) {
@@ -1198,79 +1226,96 @@ U32U64 IREmitter::ConvertFToI(size_t bitsize, bool is_signed, const F16F32F64& v
1198 } 1226 }
1199} 1227}
1200 1228
1201F16F32F64 IREmitter::ConvertSToF(size_t bitsize, const U32U64& value) { 1229F16F32F64 IREmitter::ConvertSToF(size_t dest_bitsize, size_t src_bitsize, const Value& value) {
1202 switch (bitsize) { 1230 switch (dest_bitsize) {
1203 case 16: 1231 case 16:
1204 switch (value.Type()) { 1232 switch (src_bitsize) {
1205 case Type::U32: 1233 case 8:
1234 return Inst<F16>(Opcode::ConvertF16S8, value);
1235 case 16:
1236 return Inst<F16>(Opcode::ConvertF16S16, value);
1237 case 32:
1206 return Inst<F16>(Opcode::ConvertF16S32, value); 1238 return Inst<F16>(Opcode::ConvertF16S32, value);
1207 case Type::U64: 1239 case 64:
1208 return Inst<F16>(Opcode::ConvertF16S64, value); 1240 return Inst<F16>(Opcode::ConvertF16S64, value);
1209 default:
1210 ThrowInvalidType(value.Type());
1211 } 1241 }
1242 break;
1212 case 32: 1243 case 32:
1213 switch (value.Type()) { 1244 switch (src_bitsize) {
1214 case Type::U32: 1245 case 8:
1246 return Inst<F32>(Opcode::ConvertF32S8, value);
1247 case 16:
1248 return Inst<F32>(Opcode::ConvertF32S16, value);
1249 case 32:
1215 return Inst<F32>(Opcode::ConvertF32S32, value); 1250 return Inst<F32>(Opcode::ConvertF32S32, value);
1216 case Type::U64: 1251 case 64:
1217 return Inst<F32>(Opcode::ConvertF32S64, value); 1252 return Inst<F32>(Opcode::ConvertF32S64, value);
1218 default:
1219 ThrowInvalidType(value.Type());
1220 } 1253 }
1254 break;
1221 case 64: 1255 case 64:
1222 switch (value.Type()) { 1256 switch (src_bitsize) {
1223 case Type::U32: 1257 case 8:
1224 return Inst<F16>(Opcode::ConvertF64S32, value); 1258 return Inst<F64>(Opcode::ConvertF64S8, value);
1225 case Type::U64: 1259 case 16:
1226 return Inst<F16>(Opcode::ConvertF64S64, value); 1260 return Inst<F64>(Opcode::ConvertF64S16, value);
1227 default: 1261 case 32:
1228 ThrowInvalidType(value.Type()); 1262 return Inst<F64>(Opcode::ConvertF64S32, value);
1263 case 64:
1264 return Inst<F64>(Opcode::ConvertF64S64, value);
1229 } 1265 }
1230 default: 1266 break;
1231 throw InvalidArgument("Invalid destination bitsize {}", bitsize);
1232 } 1267 }
1268 throw InvalidArgument("Invalid bit size combination dst={} src={}", dest_bitsize, src_bitsize);
1233} 1269}
1234 1270
1235F16F32F64 IREmitter::ConvertUToF(size_t bitsize, const U32U64& value) { 1271F16F32F64 IREmitter::ConvertUToF(size_t dest_bitsize, size_t src_bitsize, const Value& value) {
1236 switch (bitsize) { 1272 switch (dest_bitsize) {
1237 case 16: 1273 case 16:
1238 switch (value.Type()) { 1274 switch (src_bitsize) {
1239 case Type::U32: 1275 case 8:
1276 return Inst<F16>(Opcode::ConvertF16U8, value);
1277 case 16:
1278 return Inst<F16>(Opcode::ConvertF16U16, value);
1279 case 32:
1240 return Inst<F16>(Opcode::ConvertF16U32, value); 1280 return Inst<F16>(Opcode::ConvertF16U32, value);
1241 case Type::U64: 1281 case 64:
1242 return Inst<F16>(Opcode::ConvertF16U64, value); 1282 return Inst<F16>(Opcode::ConvertF16U64, value);
1243 default:
1244 ThrowInvalidType(value.Type());
1245 } 1283 }
1284 break;
1246 case 32: 1285 case 32:
1247 switch (value.Type()) { 1286 switch (src_bitsize) {
1248 case Type::U32: 1287 case 8:
1288 return Inst<F32>(Opcode::ConvertF32U8, value);
1289 case 16:
1290 return Inst<F32>(Opcode::ConvertF32U16, value);
1291 case 32:
1249 return Inst<F32>(Opcode::ConvertF32U32, value); 1292 return Inst<F32>(Opcode::ConvertF32U32, value);
1250 case Type::U64: 1293 case 64:
1251 return Inst<F32>(Opcode::ConvertF32U64, value); 1294 return Inst<F32>(Opcode::ConvertF32U64, value);
1252 default:
1253 ThrowInvalidType(value.Type());
1254 } 1295 }
1296 break;
1255 case 64: 1297 case 64:
1256 switch (value.Type()) { 1298 switch (src_bitsize) {
1257 case Type::U32: 1299 case 8:
1258 return Inst<F16>(Opcode::ConvertF64U32, value); 1300 return Inst<F64>(Opcode::ConvertF64U8, value);
1259 case Type::U64: 1301 case 16:
1260 return Inst<F16>(Opcode::ConvertF64U64, value); 1302 return Inst<F64>(Opcode::ConvertF64U16, value);
1261 default: 1303 case 32:
1262 ThrowInvalidType(value.Type()); 1304 return Inst<F64>(Opcode::ConvertF64U32, value);
1305 case 64:
1306 return Inst<F64>(Opcode::ConvertF64U64, value);
1263 } 1307 }
1264 default: 1308 break;
1265 throw InvalidArgument("Invalid destination bitsize {}", bitsize);
1266 } 1309 }
1310 throw InvalidArgument("Invalid bit size combination dst={} src={}", dest_bitsize, src_bitsize);
1267} 1311}
1268 1312
1269F16F32F64 IREmitter::ConvertIToF(size_t bitsize, bool is_signed, const U32U64& value) { 1313F16F32F64 IREmitter::ConvertIToF(size_t dest_bitsize, size_t src_bitsize, bool is_signed,
1314 const Value& value) {
1270 if (is_signed) { 1315 if (is_signed) {
1271 return ConvertSToF(bitsize, value); 1316 return ConvertSToF(dest_bitsize, src_bitsize, value);
1272 } else { 1317 } else {
1273 return ConvertUToF(bitsize, value); 1318 return ConvertUToF(dest_bitsize, src_bitsize, value);
1274 } 1319 }
1275} 1320}
1276 1321