Returns the ISLE constructors that are going to be used when generating this instruction. Note that one instruction might need multiple constructors, such as one for operating on memory and one for operating on registers.
(format: &Format)
| 402 | /// Note that one instruction might need multiple constructors, such as one |
| 403 | /// for operating on memory and one for operating on registers. |
| 404 | fn isle_constructors(format: &Format) -> Vec<IsleConstructor> { |
| 405 | use Mutability::*; |
| 406 | use OperandKind::*; |
| 407 | |
| 408 | let write_operands = format |
| 409 | .operands |
| 410 | .iter() |
| 411 | .filter(|o| o.mutability.is_write()) |
| 412 | .collect::<Vec<_>>(); |
| 413 | match &write_operands[..] { |
| 414 | [] => { |
| 415 | if format.eflags.is_write() { |
| 416 | vec![IsleConstructor::ProducesFlagsSideEffect] |
| 417 | } else { |
| 418 | vec![IsleConstructor::NoReturnSideEffect] |
| 419 | } |
| 420 | } |
| 421 | [one] => match one.mutability { |
| 422 | Read => unreachable!(), |
| 423 | ReadWrite | Write => match one.location.kind() { |
| 424 | Imm(_) => unreachable!(), |
| 425 | // One read/write register output? Output the instruction |
| 426 | // and that register. |
| 427 | Reg(r) | FixedReg(r) => match r.reg_class().unwrap() { |
| 428 | RegClass::Xmm => { |
| 429 | assert!(!format.eflags.is_read()); |
| 430 | vec![IsleConstructor::RetXmm] |
| 431 | } |
| 432 | RegClass::Gpr => { |
| 433 | if format.eflags.is_read() { |
| 434 | vec![IsleConstructor::ConsumesFlagsReturnsGpr] |
| 435 | } else { |
| 436 | vec![IsleConstructor::RetGpr] |
| 437 | } |
| 438 | } |
| 439 | }, |
| 440 | // One read/write memory operand? Output a side effect. |
| 441 | Mem(_) => { |
| 442 | assert!(!format.eflags.is_read()); |
| 443 | vec![IsleConstructor::RetMemorySideEffect] |
| 444 | } |
| 445 | // One read/write reg-mem output? We need constructors for |
| 446 | // both variants. |
| 447 | RegMem(rm) => match rm.reg_class().unwrap() { |
| 448 | RegClass::Xmm => { |
| 449 | assert!(!format.eflags.is_read()); |
| 450 | vec![ |
| 451 | IsleConstructor::RetXmm, |
| 452 | IsleConstructor::RetMemorySideEffect, |
| 453 | ] |
| 454 | } |
| 455 | RegClass::Gpr => { |
| 456 | if format.eflags.is_read() { |
| 457 | // FIXME: should expand this to include "consumes |
| 458 | // flags plus side effect" to model the |
| 459 | // memory-writing variant too. For example this |
| 460 | // means there's no memory-writing variant of |
| 461 | // `setcc` instructions generated. |