diff options
| author | Craig Topper <craig.topper@gmail.com> | 2013-03-14 07:09:57 +0000 | 
|---|---|---|
| committer | Craig Topper <craig.topper@gmail.com> | 2013-03-14 07:09:57 +0000 | 
| commit | a66d81d521c6cdbe4dbfc19ad65005c949f60204 (patch) | |
| tree | 235fe7b61c081b8b7d309538d76d118cccfe5983 /llvm/lib/Target | |
| parent | 20d287044c9b0771d81c30a7c6e2429ccfa85d46 (diff) | |
| download | bcm5719-llvm-a66d81d521c6cdbe4dbfc19ad65005c949f60204.tar.gz bcm5719-llvm-a66d81d521c6cdbe4dbfc19ad65005c949f60204.zip | |
Teach X86 MC instruction lowering that VMOVAPSrr and other VEX-encoded register to register moves should be switched from using the MRMSrcReg form to the MRMDestReg form if the source register is a 64-bit extended register and the destination register is not. This allows the instruction to be encoded using the 2-byte VEX form instead of the 3-byte VEX form. The GNU assembler has similar behavior.
llvm-svn: 177011
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/X86/X86MCInstLower.cpp | 42 | 
1 files changed, 42 insertions, 0 deletions
| diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp index 3af1b3e06bc..1e8347dfe45 100644 --- a/llvm/lib/Target/X86/X86MCInstLower.cpp +++ b/llvm/lib/Target/X86/X86MCInstLower.cpp @@ -407,6 +407,48 @@ ReSimplify:      LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); // MOV32r0 -> XOR32rr      break; +  // Commute operands to get a smaller encoding by using VEX.R instead of VEX.B +  // if one of the registers is extended, but other isn't. +  case X86::VMOVAPDrr: +  case X86::VMOVAPDYrr: +  case X86::VMOVAPSrr: +  case X86::VMOVAPSYrr: +  case X86::VMOVDQArr: +  case X86::VMOVDQAYrr: +  case X86::VMOVDQUrr: +  case X86::VMOVDQUYrr: +  case X86::VMOVSDrr: +  case X86::VMOVSSrr: +  case X86::VMOVUPDrr: +  case X86::VMOVUPDYrr: +  case X86::VMOVUPSrr: +  case X86::VMOVUPSYrr: { +    if (X86II::isX86_64ExtendedReg(OutMI.getOperand(0).getReg()) && +        !X86II::isX86_64ExtendedReg(OutMI.getOperand(1).getReg())) +      break; + +    unsigned NewOpc; +    switch (OutMI.getOpcode()) { +    default: llvm_unreachable("Invalid opcode"); +    case X86::VMOVAPDrr:  NewOpc = X86::VMOVAPDrr_REV;  break; +    case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break; +    case X86::VMOVAPSrr:  NewOpc = X86::VMOVAPSrr_REV;  break; +    case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break; +    case X86::VMOVDQArr:  NewOpc = X86::VMOVDQArr_REV;  break; +    case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break; +    case X86::VMOVDQUrr:  NewOpc = X86::VMOVDQUrr_REV;  break; +    case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break; +    case X86::VMOVSDrr:   NewOpc = X86::VMOVSDrr_REV;   break; +    case X86::VMOVSSrr:   NewOpc = X86::VMOVSSrr_REV;   break; +    case X86::VMOVUPDrr:  NewOpc = X86::VMOVUPDrr_REV;  break; +    case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break; +    case X86::VMOVUPSrr:  NewOpc = X86::VMOVUPSrr_REV;  break; +    case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break; +    } +    OutMI.setOpcode(NewOpc); +    break; +  } +    // TAILJMPr64, CALL64r, CALL64pcrel32 - These instructions have register    // inputs modeled as normal uses instead of implicit uses.  As such, truncate    // off all but the first operand (the callee).  FIXME: Change isel. | 

