diff options
Diffstat (limited to 'src/shader_recompiler/frontend/ir/ir_emitter.cpp')
| -rw-r--r-- | src/shader_recompiler/frontend/ir/ir_emitter.cpp | 275 |
1 files changed, 184 insertions, 91 deletions
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 1c5ae0109..9d7dc034c 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -32,16 +32,16 @@ U32 IREmitter::Imm32(s32 value) const { | |||
| 32 | return U32{Value{static_cast<u32>(value)}}; | 32 | return U32{Value{static_cast<u32>(value)}}; |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | U32 IREmitter::Imm32(f32 value) const { | 35 | F32 IREmitter::Imm32(f32 value) const { |
| 36 | return U32{Value{Common::BitCast<u32>(value)}}; | 36 | return F32{Value{value}}; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | U64 IREmitter::Imm64(u64 value) const { | 39 | U64 IREmitter::Imm64(u64 value) const { |
| 40 | return U64{Value{value}}; | 40 | return U64{Value{value}}; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | U64 IREmitter::Imm64(f64 value) const { | 43 | F64 IREmitter::Imm64(f64 value) const { |
| 44 | return U64{Value{Common::BitCast<u64>(value)}}; | 44 | return F64{Value{value}}; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | void IREmitter::Branch(IR::Block* label) { | 47 | void IREmitter::Branch(IR::Block* label) { |
| @@ -121,11 +121,11 @@ void IREmitter::SetOFlag(const U1& value) { | |||
| 121 | Inst(Opcode::SetOFlag, value); | 121 | Inst(Opcode::SetOFlag, value); |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | U32 IREmitter::GetAttribute(IR::Attribute attribute) { | 124 | F32 IREmitter::GetAttribute(IR::Attribute attribute) { |
| 125 | return Inst<U32>(Opcode::GetAttribute, attribute); | 125 | return Inst<F32>(Opcode::GetAttribute, attribute); |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | void IREmitter::SetAttribute(IR::Attribute attribute, const U32& value) { | 128 | void IREmitter::SetAttribute(IR::Attribute attribute, const F32& value) { |
| 129 | Inst(Opcode::SetAttribute, attribute, value); | 129 | Inst(Opcode::SetAttribute, attribute, value); |
| 130 | } | 130 | } |
| 131 | 131 | ||
| @@ -225,50 +225,113 @@ U1 IREmitter::GetOverflowFromOp(const Value& op) { | |||
| 225 | return Inst<U1>(Opcode::GetOverflowFromOp, op); | 225 | return Inst<U1>(Opcode::GetOverflowFromOp, op); |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | U16U32U64 IREmitter::FPAdd(const U16U32U64& a, const U16U32U64& b, FpControl control) { | 228 | F16F32F64 IREmitter::FPAdd(const F16F32F64& a, const F16F32F64& b, FpControl control) { |
| 229 | if (a.Type() != a.Type()) { | 229 | if (a.Type() != a.Type()) { |
| 230 | throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type()); | 230 | throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type()); |
| 231 | } | 231 | } |
| 232 | switch (a.Type()) { | 232 | switch (a.Type()) { |
| 233 | case Type::U16: | 233 | case Type::F16: |
| 234 | return Inst<U16>(Opcode::FPAdd16, Flags{control}, a, b); | 234 | return Inst<F16>(Opcode::FPAdd16, Flags{control}, a, b); |
| 235 | case Type::U32: | 235 | case Type::F32: |
| 236 | return Inst<U32>(Opcode::FPAdd32, Flags{control}, a, b); | 236 | return Inst<F32>(Opcode::FPAdd32, Flags{control}, a, b); |
| 237 | case Type::U64: | 237 | case Type::F64: |
| 238 | return Inst<U64>(Opcode::FPAdd64, Flags{control}, a, b); | 238 | return Inst<F64>(Opcode::FPAdd64, Flags{control}, a, b); |
| 239 | default: | 239 | default: |
| 240 | ThrowInvalidType(a.Type()); | 240 | ThrowInvalidType(a.Type()); |
| 241 | } | 241 | } |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | Value IREmitter::CompositeConstruct(const UAny& e1, const UAny& e2) { | 244 | Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2) { |
| 245 | if (e1.Type() != e2.Type()) { | 245 | if (e1.Type() != e2.Type()) { |
| 246 | throw InvalidArgument("Mismatching types {} and {}", e1.Type(), e2.Type()); | 246 | throw InvalidArgument("Mismatching types {} and {}", e1.Type(), e2.Type()); |
| 247 | } | 247 | } |
| 248 | return Inst(Opcode::CompositeConstruct2, e1, e2); | 248 | switch (e1.Type()) { |
| 249 | case Type::U32: | ||
| 250 | return Inst(Opcode::CompositeConstructU32x2, e1, e2); | ||
| 251 | case Type::F16: | ||
| 252 | return Inst(Opcode::CompositeConstructF16x2, e1, e2); | ||
| 253 | case Type::F32: | ||
| 254 | return Inst(Opcode::CompositeConstructF32x2, e1, e2); | ||
| 255 | case Type::F64: | ||
| 256 | return Inst(Opcode::CompositeConstructF64x2, e1, e2); | ||
| 257 | default: | ||
| 258 | ThrowInvalidType(e1.Type()); | ||
| 259 | } | ||
| 249 | } | 260 | } |
| 250 | 261 | ||
| 251 | Value IREmitter::CompositeConstruct(const UAny& e1, const UAny& e2, const UAny& e3) { | 262 | Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2, const Value& e3) { |
| 252 | if (e1.Type() != e2.Type() || e1.Type() != e3.Type()) { | 263 | if (e1.Type() != e2.Type() || e1.Type() != e3.Type()) { |
| 253 | throw InvalidArgument("Mismatching types {}, {}, and {}", e1.Type(), e2.Type(), e3.Type()); | 264 | throw InvalidArgument("Mismatching types {}, {}, and {}", e1.Type(), e2.Type(), e3.Type()); |
| 254 | } | 265 | } |
| 255 | return Inst(Opcode::CompositeConstruct3, e1, e2, e3); | 266 | switch (e1.Type()) { |
| 267 | case Type::U32: | ||
| 268 | return Inst(Opcode::CompositeConstructU32x3, e1, e2, e3); | ||
| 269 | case Type::F16: | ||
| 270 | return Inst(Opcode::CompositeConstructF16x3, e1, e2, e3); | ||
| 271 | case Type::F32: | ||
| 272 | return Inst(Opcode::CompositeConstructF32x3, e1, e2, e3); | ||
| 273 | case Type::F64: | ||
| 274 | return Inst(Opcode::CompositeConstructF64x3, e1, e2, e3); | ||
| 275 | default: | ||
| 276 | ThrowInvalidType(e1.Type()); | ||
| 277 | } | ||
| 256 | } | 278 | } |
| 257 | 279 | ||
| 258 | Value IREmitter::CompositeConstruct(const UAny& e1, const UAny& e2, const UAny& e3, | 280 | Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2, const Value& e3, |
| 259 | const UAny& e4) { | 281 | const Value& e4) { |
| 260 | if (e1.Type() != e2.Type() || e1.Type() != e3.Type() || e1.Type() != e4.Type()) { | 282 | if (e1.Type() != e2.Type() || e1.Type() != e3.Type() || e1.Type() != e4.Type()) { |
| 261 | throw InvalidArgument("Mismatching types {}, {}, {}, and {}", e1.Type(), e2.Type(), | 283 | throw InvalidArgument("Mismatching types {}, {}, {}, and {}", e1.Type(), e2.Type(), |
| 262 | e3.Type(), e4.Type()); | 284 | e3.Type(), e4.Type()); |
| 263 | } | 285 | } |
| 264 | return Inst(Opcode::CompositeConstruct4, e1, e2, e3, e4); | 286 | switch (e1.Type()) { |
| 287 | case Type::U32: | ||
| 288 | return Inst(Opcode::CompositeConstructU32x4, e1, e2, e3, e4); | ||
| 289 | case Type::F16: | ||
| 290 | return Inst(Opcode::CompositeConstructF16x4, e1, e2, e3, e4); | ||
| 291 | case Type::F32: | ||
| 292 | return Inst(Opcode::CompositeConstructF32x4, e1, e2, e3, e4); | ||
| 293 | case Type::F64: | ||
| 294 | return Inst(Opcode::CompositeConstructF64x4, e1, e2, e3, e4); | ||
| 295 | default: | ||
| 296 | ThrowInvalidType(e1.Type()); | ||
| 297 | } | ||
| 265 | } | 298 | } |
| 266 | 299 | ||
| 267 | UAny IREmitter::CompositeExtract(const Value& vector, size_t element) { | 300 | Value IREmitter::CompositeExtract(const Value& vector, size_t element) { |
| 268 | if (element >= 4) { | 301 | const auto read = [&](Opcode opcode, size_t limit) -> Value { |
| 269 | throw InvalidArgument("Out of bounds element {}", element); | 302 | if (element >= limit) { |
| 303 | throw InvalidArgument("Out of bounds element {}", element); | ||
| 304 | } | ||
| 305 | return Inst(opcode, vector, Value{static_cast<u32>(element)}); | ||
| 306 | }; | ||
| 307 | switch (vector.Type()) { | ||
| 308 | case Type::U32x2: | ||
| 309 | return read(Opcode::CompositeExtractU32x2, 2); | ||
| 310 | case Type::U32x3: | ||
| 311 | return read(Opcode::CompositeExtractU32x3, 3); | ||
| 312 | case Type::U32x4: | ||
| 313 | return read(Opcode::CompositeExtractU32x4, 4); | ||
| 314 | case Type::F16x2: | ||
| 315 | return read(Opcode::CompositeExtractF16x2, 2); | ||
| 316 | case Type::F16x3: | ||
| 317 | return read(Opcode::CompositeExtractF16x3, 3); | ||
| 318 | case Type::F16x4: | ||
| 319 | return read(Opcode::CompositeExtractF16x4, 4); | ||
| 320 | case Type::F32x2: | ||
| 321 | return read(Opcode::CompositeExtractF32x2, 2); | ||
| 322 | case Type::F32x3: | ||
| 323 | return read(Opcode::CompositeExtractF32x3, 3); | ||
| 324 | case Type::F32x4: | ||
| 325 | return read(Opcode::CompositeExtractF32x4, 4); | ||
| 326 | case Type::F64x2: | ||
| 327 | return read(Opcode::CompositeExtractF64x2, 2); | ||
| 328 | case Type::F64x3: | ||
| 329 | return read(Opcode::CompositeExtractF64x3, 3); | ||
| 330 | case Type::F64x4: | ||
| 331 | return read(Opcode::CompositeExtractF64x4, 4); | ||
| 332 | default: | ||
| 333 | ThrowInvalidType(vector.Type()); | ||
| 270 | } | 334 | } |
| 271 | return Inst<UAny>(Opcode::CompositeExtract, vector, Imm32(static_cast<u32>(element))); | ||
| 272 | } | 335 | } |
| 273 | 336 | ||
| 274 | UAny IREmitter::Select(const U1& condition, const UAny& true_value, const UAny& false_value) { | 337 | UAny IREmitter::Select(const U1& condition, const UAny& true_value, const UAny& false_value) { |
| @@ -289,6 +352,36 @@ UAny IREmitter::Select(const U1& condition, const UAny& true_value, const UAny& | |||
| 289 | } | 352 | } |
| 290 | } | 353 | } |
| 291 | 354 | ||
| 355 | template <> | ||
| 356 | IR::U32 IREmitter::BitCast<IR::U32, IR::F32>(const IR::F32& value) { | ||
| 357 | return Inst<IR::U32>(Opcode::BitCastU32F32, value); | ||
| 358 | } | ||
| 359 | |||
| 360 | template <> | ||
| 361 | IR::F32 IREmitter::BitCast<IR::F32, IR::U32>(const IR::U32& value) { | ||
| 362 | return Inst<IR::F32>(Opcode::BitCastF32U32, value); | ||
| 363 | } | ||
| 364 | |||
| 365 | template <> | ||
| 366 | IR::U16 IREmitter::BitCast<IR::U16, IR::F16>(const IR::F16& value) { | ||
| 367 | return Inst<IR::U16>(Opcode::BitCastU16F16, value); | ||
| 368 | } | ||
| 369 | |||
| 370 | template <> | ||
| 371 | IR::F16 IREmitter::BitCast<IR::F16, IR::U16>(const IR::U16& value) { | ||
| 372 | return Inst<IR::F16>(Opcode::BitCastF16U16, value); | ||
| 373 | } | ||
| 374 | |||
| 375 | template <> | ||
| 376 | IR::U64 IREmitter::BitCast<IR::U64, IR::F64>(const IR::F64& value) { | ||
| 377 | return Inst<IR::U64>(Opcode::BitCastU64F64, value); | ||
| 378 | } | ||
| 379 | |||
| 380 | template <> | ||
| 381 | IR::F64 IREmitter::BitCast<IR::F64, IR::U64>(const IR::U64& value) { | ||
| 382 | return Inst<IR::F64>(Opcode::BitCastF64U64, value); | ||
| 383 | } | ||
| 384 | |||
| 292 | U64 IREmitter::PackUint2x32(const Value& vector) { | 385 | U64 IREmitter::PackUint2x32(const Value& vector) { |
| 293 | return Inst<U64>(Opcode::PackUint2x32, vector); | 386 | return Inst<U64>(Opcode::PackUint2x32, vector); |
| 294 | } | 387 | } |
| @@ -305,75 +398,75 @@ Value IREmitter::UnpackFloat2x16(const U32& value) { | |||
| 305 | return Inst<Value>(Opcode::UnpackFloat2x16, value); | 398 | return Inst<Value>(Opcode::UnpackFloat2x16, value); |
| 306 | } | 399 | } |
| 307 | 400 | ||
| 308 | U64 IREmitter::PackDouble2x32(const Value& vector) { | 401 | F64 IREmitter::PackDouble2x32(const Value& vector) { |
| 309 | return Inst<U64>(Opcode::PackDouble2x32, vector); | 402 | return Inst<F64>(Opcode::PackDouble2x32, vector); |
| 310 | } | 403 | } |
| 311 | 404 | ||
| 312 | Value IREmitter::UnpackDouble2x32(const U64& value) { | 405 | Value IREmitter::UnpackDouble2x32(const F64& value) { |
| 313 | return Inst<Value>(Opcode::UnpackDouble2x32, value); | 406 | return Inst<Value>(Opcode::UnpackDouble2x32, value); |
| 314 | } | 407 | } |
| 315 | 408 | ||
| 316 | U16U32U64 IREmitter::FPMul(const U16U32U64& a, const U16U32U64& b, FpControl control) { | 409 | F16F32F64 IREmitter::FPMul(const F16F32F64& a, const F16F32F64& b, FpControl control) { |
| 317 | if (a.Type() != b.Type()) { | 410 | if (a.Type() != b.Type()) { |
| 318 | throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type()); | 411 | throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type()); |
| 319 | } | 412 | } |
| 320 | switch (a.Type()) { | 413 | switch (a.Type()) { |
| 321 | case Type::U16: | 414 | case Type::F16: |
| 322 | return Inst<U16>(Opcode::FPMul16, Flags{control}, a, b); | 415 | return Inst<F16>(Opcode::FPMul16, Flags{control}, a, b); |
| 323 | case Type::U32: | 416 | case Type::F32: |
| 324 | return Inst<U32>(Opcode::FPMul32, Flags{control}, a, b); | 417 | return Inst<F32>(Opcode::FPMul32, Flags{control}, a, b); |
| 325 | case Type::U64: | 418 | case Type::F64: |
| 326 | return Inst<U64>(Opcode::FPMul64, Flags{control}, a, b); | 419 | return Inst<F64>(Opcode::FPMul64, Flags{control}, a, b); |
| 327 | default: | 420 | default: |
| 328 | ThrowInvalidType(a.Type()); | 421 | ThrowInvalidType(a.Type()); |
| 329 | } | 422 | } |
| 330 | } | 423 | } |
| 331 | 424 | ||
| 332 | U16U32U64 IREmitter::FPFma(const U16U32U64& a, const U16U32U64& b, const U16U32U64& c, | 425 | F16F32F64 IREmitter::FPFma(const F16F32F64& a, const F16F32F64& b, const F16F32F64& c, |
| 333 | FpControl control) { | 426 | FpControl control) { |
| 334 | if (a.Type() != b.Type() || a.Type() != c.Type()) { | 427 | if (a.Type() != b.Type() || a.Type() != c.Type()) { |
| 335 | throw InvalidArgument("Mismatching types {}, {}, and {}", a.Type(), b.Type(), c.Type()); | 428 | throw InvalidArgument("Mismatching types {}, {}, and {}", a.Type(), b.Type(), c.Type()); |
| 336 | } | 429 | } |
| 337 | switch (a.Type()) { | 430 | switch (a.Type()) { |
| 338 | case Type::U16: | 431 | case Type::F16: |
| 339 | return Inst<U16>(Opcode::FPFma16, Flags{control}, a, b, c); | 432 | return Inst<F16>(Opcode::FPFma16, Flags{control}, a, b, c); |
| 340 | case Type::U32: | 433 | case Type::F32: |
| 341 | return Inst<U32>(Opcode::FPFma32, Flags{control}, a, b, c); | 434 | return Inst<F32>(Opcode::FPFma32, Flags{control}, a, b, c); |
| 342 | case Type::U64: | 435 | case Type::F64: |
| 343 | return Inst<U64>(Opcode::FPFma64, Flags{control}, a, b, c); | 436 | return Inst<F64>(Opcode::FPFma64, Flags{control}, a, b, c); |
| 344 | default: | 437 | default: |
| 345 | ThrowInvalidType(a.Type()); | 438 | ThrowInvalidType(a.Type()); |
| 346 | } | 439 | } |
| 347 | } | 440 | } |
| 348 | 441 | ||
| 349 | U16U32U64 IREmitter::FPAbs(const U16U32U64& value) { | 442 | F16F32F64 IREmitter::FPAbs(const F16F32F64& value) { |
| 350 | switch (value.Type()) { | 443 | switch (value.Type()) { |
| 351 | case Type::U16: | 444 | case Type::U16: |
| 352 | return Inst<U16>(Opcode::FPAbs16, value); | 445 | return Inst<F16>(Opcode::FPAbs16, value); |
| 353 | case Type::U32: | 446 | case Type::U32: |
| 354 | return Inst<U32>(Opcode::FPAbs32, value); | 447 | return Inst<F32>(Opcode::FPAbs32, value); |
| 355 | case Type::U64: | 448 | case Type::U64: |
| 356 | return Inst<U64>(Opcode::FPAbs64, value); | 449 | return Inst<F64>(Opcode::FPAbs64, value); |
| 357 | default: | 450 | default: |
| 358 | ThrowInvalidType(value.Type()); | 451 | ThrowInvalidType(value.Type()); |
| 359 | } | 452 | } |
| 360 | } | 453 | } |
| 361 | 454 | ||
| 362 | U16U32U64 IREmitter::FPNeg(const U16U32U64& value) { | 455 | F16F32F64 IREmitter::FPNeg(const F16F32F64& value) { |
| 363 | switch (value.Type()) { | 456 | switch (value.Type()) { |
| 364 | case Type::U16: | 457 | case Type::U16: |
| 365 | return Inst<U16>(Opcode::FPNeg16, value); | 458 | return Inst<F16>(Opcode::FPNeg16, value); |
| 366 | case Type::U32: | 459 | case Type::U32: |
| 367 | return Inst<U32>(Opcode::FPNeg32, value); | 460 | return Inst<F32>(Opcode::FPNeg32, value); |
| 368 | case Type::U64: | 461 | case Type::U64: |
| 369 | return Inst<U64>(Opcode::FPNeg64, value); | 462 | return Inst<F64>(Opcode::FPNeg64, value); |
| 370 | default: | 463 | default: |
| 371 | ThrowInvalidType(value.Type()); | 464 | ThrowInvalidType(value.Type()); |
| 372 | } | 465 | } |
| 373 | } | 466 | } |
| 374 | 467 | ||
| 375 | U16U32U64 IREmitter::FPAbsNeg(const U16U32U64& value, bool abs, bool neg) { | 468 | F16F32F64 IREmitter::FPAbsNeg(const F16F32F64& value, bool abs, bool neg) { |
| 376 | U16U32U64 result{value}; | 469 | F16F32F64 result{value}; |
| 377 | if (abs) { | 470 | if (abs) { |
| 378 | result = FPAbs(value); | 471 | result = FPAbs(value); |
| 379 | } | 472 | } |
| @@ -383,108 +476,108 @@ U16U32U64 IREmitter::FPAbsNeg(const U16U32U64& value, bool abs, bool neg) { | |||
| 383 | return result; | 476 | return result; |
| 384 | } | 477 | } |
| 385 | 478 | ||
| 386 | U32 IREmitter::FPCosNotReduced(const U32& value) { | 479 | F32 IREmitter::FPCosNotReduced(const F32& value) { |
| 387 | return Inst<U32>(Opcode::FPCosNotReduced, value); | 480 | return Inst<F32>(Opcode::FPCosNotReduced, value); |
| 388 | } | 481 | } |
| 389 | 482 | ||
| 390 | U32 IREmitter::FPExp2NotReduced(const U32& value) { | 483 | F32 IREmitter::FPExp2NotReduced(const F32& value) { |
| 391 | return Inst<U32>(Opcode::FPExp2NotReduced, value); | 484 | return Inst<F32>(Opcode::FPExp2NotReduced, value); |
| 392 | } | 485 | } |
| 393 | 486 | ||
| 394 | U32 IREmitter::FPLog2(const U32& value) { | 487 | F32 IREmitter::FPLog2(const F32& value) { |
| 395 | return Inst<U32>(Opcode::FPLog2, value); | 488 | return Inst<F32>(Opcode::FPLog2, value); |
| 396 | } | 489 | } |
| 397 | 490 | ||
| 398 | U32U64 IREmitter::FPRecip(const U32U64& value) { | 491 | F32F64 IREmitter::FPRecip(const F32F64& value) { |
| 399 | switch (value.Type()) { | 492 | switch (value.Type()) { |
| 400 | case Type::U32: | 493 | case Type::U32: |
| 401 | return Inst<U32>(Opcode::FPRecip32, value); | 494 | return Inst<F32>(Opcode::FPRecip32, value); |
| 402 | case Type::U64: | 495 | case Type::U64: |
| 403 | return Inst<U64>(Opcode::FPRecip64, value); | 496 | return Inst<F64>(Opcode::FPRecip64, value); |
| 404 | default: | 497 | default: |
| 405 | ThrowInvalidType(value.Type()); | 498 | ThrowInvalidType(value.Type()); |
| 406 | } | 499 | } |
| 407 | } | 500 | } |
| 408 | 501 | ||
| 409 | U32U64 IREmitter::FPRecipSqrt(const U32U64& value) { | 502 | F32F64 IREmitter::FPRecipSqrt(const F32F64& value) { |
| 410 | switch (value.Type()) { | 503 | switch (value.Type()) { |
| 411 | case Type::U32: | 504 | case Type::U32: |
| 412 | return Inst<U32>(Opcode::FPRecipSqrt32, value); | 505 | return Inst<F32>(Opcode::FPRecipSqrt32, value); |
| 413 | case Type::U64: | 506 | case Type::U64: |
| 414 | return Inst<U64>(Opcode::FPRecipSqrt64, value); | 507 | return Inst<F64>(Opcode::FPRecipSqrt64, value); |
| 415 | default: | 508 | default: |
| 416 | ThrowInvalidType(value.Type()); | 509 | ThrowInvalidType(value.Type()); |
| 417 | } | 510 | } |
| 418 | } | 511 | } |
| 419 | 512 | ||
| 420 | U32 IREmitter::FPSinNotReduced(const U32& value) { | 513 | F32 IREmitter::FPSinNotReduced(const F32& value) { |
| 421 | return Inst<U32>(Opcode::FPSinNotReduced, value); | 514 | return Inst<F32>(Opcode::FPSinNotReduced, value); |
| 422 | } | 515 | } |
| 423 | 516 | ||
| 424 | U32 IREmitter::FPSqrt(const U32& value) { | 517 | F32 IREmitter::FPSqrt(const F32& value) { |
| 425 | return Inst<U32>(Opcode::FPSqrt, value); | 518 | return Inst<F32>(Opcode::FPSqrt, value); |
| 426 | } | 519 | } |
| 427 | 520 | ||
| 428 | U16U32U64 IREmitter::FPSaturate(const U16U32U64& value) { | 521 | F16F32F64 IREmitter::FPSaturate(const F16F32F64& value) { |
| 429 | switch (value.Type()) { | 522 | switch (value.Type()) { |
| 430 | case Type::U16: | 523 | case Type::U16: |
| 431 | return Inst<U16>(Opcode::FPSaturate16, value); | 524 | return Inst<F16>(Opcode::FPSaturate16, value); |
| 432 | case Type::U32: | 525 | case Type::U32: |
| 433 | return Inst<U32>(Opcode::FPSaturate32, value); | 526 | return Inst<F32>(Opcode::FPSaturate32, value); |
| 434 | case Type::U64: | 527 | case Type::U64: |
| 435 | return Inst<U64>(Opcode::FPSaturate64, value); | 528 | return Inst<F64>(Opcode::FPSaturate64, value); |
| 436 | default: | 529 | default: |
| 437 | ThrowInvalidType(value.Type()); | 530 | ThrowInvalidType(value.Type()); |
| 438 | } | 531 | } |
| 439 | } | 532 | } |
| 440 | 533 | ||
| 441 | U16U32U64 IREmitter::FPRoundEven(const U16U32U64& value) { | 534 | F16F32F64 IREmitter::FPRoundEven(const F16F32F64& value) { |
| 442 | switch (value.Type()) { | 535 | switch (value.Type()) { |
| 443 | case Type::U16: | 536 | case Type::U16: |
| 444 | return Inst<U16>(Opcode::FPRoundEven16, value); | 537 | return Inst<F16>(Opcode::FPRoundEven16, value); |
| 445 | case Type::U32: | 538 | case Type::U32: |
| 446 | return Inst<U32>(Opcode::FPRoundEven32, value); | 539 | return Inst<F32>(Opcode::FPRoundEven32, value); |
| 447 | case Type::U64: | 540 | case Type::U64: |
| 448 | return Inst<U64>(Opcode::FPRoundEven64, value); | 541 | return Inst<F64>(Opcode::FPRoundEven64, value); |
| 449 | default: | 542 | default: |
| 450 | ThrowInvalidType(value.Type()); | 543 | ThrowInvalidType(value.Type()); |
| 451 | } | 544 | } |
| 452 | } | 545 | } |
| 453 | 546 | ||
| 454 | U16U32U64 IREmitter::FPFloor(const U16U32U64& value) { | 547 | F16F32F64 IREmitter::FPFloor(const F16F32F64& value) { |
| 455 | switch (value.Type()) { | 548 | switch (value.Type()) { |
| 456 | case Type::U16: | 549 | case Type::U16: |
| 457 | return Inst<U16>(Opcode::FPFloor16, value); | 550 | return Inst<F16>(Opcode::FPFloor16, value); |
| 458 | case Type::U32: | 551 | case Type::U32: |
| 459 | return Inst<U32>(Opcode::FPFloor32, value); | 552 | return Inst<F32>(Opcode::FPFloor32, value); |
| 460 | case Type::U64: | 553 | case Type::U64: |
| 461 | return Inst<U64>(Opcode::FPFloor64, value); | 554 | return Inst<F64>(Opcode::FPFloor64, value); |
| 462 | default: | 555 | default: |
| 463 | ThrowInvalidType(value.Type()); | 556 | ThrowInvalidType(value.Type()); |
| 464 | } | 557 | } |
| 465 | } | 558 | } |
| 466 | 559 | ||
| 467 | U16U32U64 IREmitter::FPCeil(const U16U32U64& value) { | 560 | F16F32F64 IREmitter::FPCeil(const F16F32F64& value) { |
| 468 | switch (value.Type()) { | 561 | switch (value.Type()) { |
| 469 | case Type::U16: | 562 | case Type::U16: |
| 470 | return Inst<U16>(Opcode::FPCeil16, value); | 563 | return Inst<F16>(Opcode::FPCeil16, value); |
| 471 | case Type::U32: | 564 | case Type::U32: |
| 472 | return Inst<U32>(Opcode::FPCeil32, value); | 565 | return Inst<F32>(Opcode::FPCeil32, value); |
| 473 | case Type::U64: | 566 | case Type::U64: |
| 474 | return Inst<U64>(Opcode::FPCeil64, value); | 567 | return Inst<F64>(Opcode::FPCeil64, value); |
| 475 | default: | 568 | default: |
| 476 | ThrowInvalidType(value.Type()); | 569 | ThrowInvalidType(value.Type()); |
| 477 | } | 570 | } |
| 478 | } | 571 | } |
| 479 | 572 | ||
| 480 | U16U32U64 IREmitter::FPTrunc(const U16U32U64& value) { | 573 | F16F32F64 IREmitter::FPTrunc(const F16F32F64& value) { |
| 481 | switch (value.Type()) { | 574 | switch (value.Type()) { |
| 482 | case Type::U16: | 575 | case Type::U16: |
| 483 | return Inst<U16>(Opcode::FPTrunc16, value); | 576 | return Inst<F16>(Opcode::FPTrunc16, value); |
| 484 | case Type::U32: | 577 | case Type::U32: |
| 485 | return Inst<U32>(Opcode::FPTrunc32, value); | 578 | return Inst<F32>(Opcode::FPTrunc32, value); |
| 486 | case Type::U64: | 579 | case Type::U64: |
| 487 | return Inst<U64>(Opcode::FPTrunc64, value); | 580 | return Inst<F64>(Opcode::FPTrunc64, value); |
| 488 | default: | 581 | default: |
| 489 | ThrowInvalidType(value.Type()); | 582 | ThrowInvalidType(value.Type()); |
| 490 | } | 583 | } |
| @@ -605,7 +698,7 @@ U1 IREmitter::LogicalNot(const U1& value) { | |||
| 605 | return Inst<U1>(Opcode::LogicalNot, value); | 698 | return Inst<U1>(Opcode::LogicalNot, value); |
| 606 | } | 699 | } |
| 607 | 700 | ||
| 608 | U32U64 IREmitter::ConvertFToS(size_t bitsize, const U16U32U64& value) { | 701 | U32U64 IREmitter::ConvertFToS(size_t bitsize, const F16F32F64& value) { |
| 609 | switch (bitsize) { | 702 | switch (bitsize) { |
| 610 | case 16: | 703 | case 16: |
| 611 | switch (value.Type()) { | 704 | switch (value.Type()) { |
| @@ -645,7 +738,7 @@ U32U64 IREmitter::ConvertFToS(size_t bitsize, const U16U32U64& value) { | |||
| 645 | } | 738 | } |
| 646 | } | 739 | } |
| 647 | 740 | ||
| 648 | U32U64 IREmitter::ConvertFToU(size_t bitsize, const U16U32U64& value) { | 741 | U32U64 IREmitter::ConvertFToU(size_t bitsize, const F16F32F64& value) { |
| 649 | switch (bitsize) { | 742 | switch (bitsize) { |
| 650 | case 16: | 743 | case 16: |
| 651 | switch (value.Type()) { | 744 | switch (value.Type()) { |
| @@ -685,7 +778,7 @@ U32U64 IREmitter::ConvertFToU(size_t bitsize, const U16U32U64& value) { | |||
| 685 | } | 778 | } |
| 686 | } | 779 | } |
| 687 | 780 | ||
| 688 | U32U64 IREmitter::ConvertFToI(size_t bitsize, bool is_signed, const U16U32U64& value) { | 781 | U32U64 IREmitter::ConvertFToI(size_t bitsize, bool is_signed, const F16F32F64& value) { |
| 689 | if (is_signed) { | 782 | if (is_signed) { |
| 690 | return ConvertFToS(bitsize, value); | 783 | return ConvertFToS(bitsize, value); |
| 691 | } else { | 784 | } else { |