OLD | NEW |
(Empty) | |
| 1 //====- X86InstrNaCl.td - Describe NaCl Instructions ----*- tablegen -*-===// |
| 2 // |
| 3 // The LLVM Compiler Infrastructure |
| 4 // |
| 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. |
| 7 // |
| 8 //===----------------------------------------------------------------------===// |
| 9 // |
| 10 // This file describes the modifications to the X86 instruction set needed for |
| 11 // Native Client code generation. |
| 12 // |
| 13 //===----------------------------------------------------------------------===// |
| 14 |
| 15 |
| 16 //===----------------------------------------------------------------------===// |
| 17 // NaCl specific DAG Nodes. |
| 18 // |
| 19 |
| 20 //===----------------------------------------------------------------------===// |
| 21 // |
| 22 // Native Client Pseudo-Instructions |
| 23 // |
| 24 // These instructions implement the Native Client pseudo-instructions, such |
| 25 // as nacljmp and naclasp. |
| 26 // |
| 27 // TableGen and MC consider these to be "real" instructions. They can be |
| 28 // parsed by the AsmParser and emitted by the AsmStreamer as if they |
| 29 // were just regular instructions. They are not marked "Pseudo" because |
| 30 // this would imply isCodeGenOnly=1, which would stop them from being |
| 31 // parsed by the assembler. |
| 32 // |
| 33 // These instructions cannot be encoded (written into an object file) by the |
| 34 // MCCodeEmitter. Instead, during direct object emission, they get lowered to |
| 35 // a sequence of streamer emits. (see X86InstrNaCl.cpp) |
| 36 // |
| 37 // These instructions should not be used in CodeGen. They have no pattern |
| 38 // and lack CodeGen metadata. Instead, the X86NaClRewritePass should |
| 39 // generate these instructions after CodeGen is finished. |
| 40 // |
| 41 //===----------------------------------------------------------------------===// |
| 42 |
| 43 |
| 44 //===----------------------------------------------------------------------===// |
| 45 // 32-bit Native Client Pseudo Instructions |
| 46 //===----------------------------------------------------------------------===// |
| 47 |
| 48 class NaClPI32<dag outs, dag ins, string asm> |
| 49 : I<0, CustomFrm, outs, ins, asm, []>, Requires<[IsNaCl, Not64BitMode]>; |
| 50 |
| 51 let isTerminator = 1, isReturn = 1, isBarrier = 1, |
| 52 hasCtrlDep = 1, FPForm = SpecialFP, isAsmParserOnly = 1 in { |
| 53 def NACL_RET32 : NaClPI32<(outs), (ins), "naclret">; |
| 54 def NACL_RETI32 : NaClPI32<(outs), (ins i16imm:$amt), "naclreti\t$amt">; |
| 55 } |
| 56 |
| 57 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1, |
| 58 isAsmParserOnly = 1 in { |
| 59 def NACL_JMP32r : NaClPI32<(outs), (ins GR32:$dst), "nacljmp\t$dst">; |
| 60 } |
| 61 |
| 62 let isCall = 1, isAsmParserOnly = 1 in { |
| 63 def NACL_CALL32r : NaClPI32<(outs), (ins GR32:$dst), |
| 64 "naclcall\t$dst">; |
| 65 } |
| 66 |
| 67 |
| 68 //===----------------------------------------------------------------------===// |
| 69 // 64-bit Native Client Pseudo Instructions |
| 70 //===----------------------------------------------------------------------===// |
| 71 |
| 72 class NaClPI64<dag outs, dag ins, string asm> |
| 73 : I<0, CustomFrm, outs, ins, asm, []>, Requires<[IsNaCl, In64BitMode]>; |
| 74 |
| 75 let isTerminator = 1, isReturn = 1, isBarrier = 1, |
| 76 hasCtrlDep = 1, FPForm = SpecialFP, isAsmParserOnly = 1 in { |
| 77 def NACL_RET64 : NaClPI64<(outs), (ins), "naclret">; |
| 78 } |
| 79 |
| 80 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1, |
| 81 isAsmParserOnly = 1 in { |
| 82 def NACL_JMP64r : NaClPI64<(outs), (ins GR32:$dst, GR64:$rZP), |
| 83 "nacljmp\t{$dst, $rZP|$rZP, $dst}">; |
| 84 def NACL_JMP64z : NaClPI64<(outs), (ins GR32:$dst), |
| 85 "nacljmp\t$dst">; |
| 86 } |
| 87 |
| 88 |
| 89 let isCall = 1, isAsmParserOnly = 1 in { |
| 90 def NACL_CALL64d : NaClPI64<(outs), (ins i32imm_pcrel:$dst), |
| 91 "call{q}\t$dst">; |
| 92 def NACL_CALL64r : NaClPI64<(outs), (ins GR32:$dst, GR64:$rZP), |
| 93 "naclcall\t$dst,$rZP">; |
| 94 } |
| 95 |
| 96 let Defs = [RSP, EFLAGS], Uses = [RSP], isAsmParserOnly = 1 in { |
| 97 def NACL_ASPi8 : NaClPI64<(outs), (ins i64i8imm:$off, GR64:$rZP), |
| 98 "naclasp{q}\t{$off, $rZP|$rZP, $off}">; |
| 99 |
| 100 def NACL_ASPi32: NaClPI64<(outs), (ins i64i32imm:$off, GR64:$rZP), |
| 101 "naclasp{q}\t{$off, $rZP|$rZP, $off}">; |
| 102 |
| 103 def NACL_SSPi8 : NaClPI64<(outs), (ins i64i8imm:$off, GR64:$rZP), |
| 104 "naclssp{q}\t{$off, $rZP|$rZP, $off}">; |
| 105 |
| 106 def NACL_SSPi32: NaClPI64<(outs), (ins i64i32imm:$off, GR64:$rZP), |
| 107 "naclssp{q}\t{$off, $rZP|$rZP, $off}">; |
| 108 |
| 109 def NACL_ANDSPi8: NaClPI64<(outs), (ins i64i8imm:$off, GR64:$rZP), |
| 110 "naclandsp{q}\t{$off, $rZP|$rZP, $off}">; |
| 111 |
| 112 def NACL_ANDSPi32: NaClPI64<(outs), (ins i64i32imm:$off, GR64:$rZP), |
| 113 "naclandsp{q}\t{$off, $rZP|$rZP, $off}">; |
| 114 } |
| 115 |
| 116 let Defs = [RSP], Uses = [RBP], isAsmParserOnly = 1 in { |
| 117 def NACL_SPADJi32 : NaClPI64<(outs), (ins i64i32imm:$off, GR64:$rZP), |
| 118 "naclspadj\t{$off, $rZP|$rZP, $off}">; |
| 119 } |
| 120 |
| 121 let Defs = [RSP], isAsmParserOnly = 1 in { |
| 122 def NACL_RESTSPr : NaClPI64<(outs), (ins GR32:$src, GR64:$rZP), |
| 123 "naclrestsp_noflags\t{$src, $rZP|$rZP, $src}">; |
| 124 def NACL_RESTSPm : NaClPI64<(outs), (ins i32mem:$src, GR64:$rZP), |
| 125 "naclrestsp_noflags\t{$src, $rZP|$rZP, $src}">; |
| 126 def NACL_RESTSPrz : NaClPI64<(outs), (ins GR32:$src), |
| 127 "naclrestsp_noflags\t$src">; |
| 128 } |
| 129 |
| 130 def : MnemonicAlias<"naclrestsp", "naclrestsp_noflags">; |
| 131 |
| 132 let Defs = [RBP], isAsmParserOnly = 1 in { |
| 133 def NACL_RESTBPr : NaClPI64<(outs), (ins GR32:$src, GR64:$rZP), |
| 134 "naclrestbp\t{$src, $rZP|$rZP, $src}">; |
| 135 def NACL_RESTBPm : NaClPI64<(outs), (ins i32mem:$src, GR64:$rZP), |
| 136 "naclrestbp\t{$src, $rZP|$rZP, $src}">; |
| 137 def NACL_RESTBPrz : NaClPI64<(outs), (ins GR32:$src), |
| 138 "naclrestbp\t$src">; |
| 139 } |
| 140 |
| 141 //===----------------------------------------------------------------------===// |
| 142 // |
| 143 // Code Generator Instructions (isCodeGenOnly == 1) |
| 144 // |
| 145 // These instructions exists to make CodeGen work with Native Client's |
| 146 // modifications. |
| 147 // |
| 148 // Many of these instructions exist because of limitations in CodeGen |
| 149 // or TableGen, and may become unnecessary in the future. |
| 150 //===----------------------------------------------------------------------===// |
| 151 |
| 152 //===----------------------------------------------------------------------===// |
| 153 // |
| 154 // CodeGen 64-bit |
| 155 // |
| 156 //===----------------------------------------------------------------------===// |
| 157 |
| 158 |
| 159 // Because pointers are 32-bit on X86-64 Native Client, we need to |
| 160 // produce new versions of the JMP64/CALL64 instructions which can accept |
| 161 // addresses which are i32 instead of i64. |
| 162 // |
| 163 // Indirect calls have been changed to zero extend i32 to i64, so |
| 164 // we don't need a NaCl-specific CALL64r. We could possibly do the same for |
| 165 // indirect branches (switch jump tables) and direct calls. |
| 166 |
| 167 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { |
| 168 def NACL_CG_JMP64r : I<0, Pseudo, (outs), (ins GR32:$dst), |
| 169 "nacljmp\t$dst", |
| 170 [(brind GR32:$dst)]>, |
| 171 Requires<[IsNaCl, In64BitMode]>; |
| 172 } |
| 173 |
| 174 // RSP is marked as a use to prevent stack-pointer assignments that appear |
| 175 // immediately before calls from potentially appearing dead. Uses for argument |
| 176 // registers are added manually. |
| 177 let isCall = 1, Uses = [RSP] in { |
| 178 def NACL_CG_CALL64pcrel32 : I<0, Pseudo, (outs), |
| 179 (ins i32imm_pcrel:$dst), |
| 180 "call{q}\t$dst", []>, |
| 181 Requires<[IsNaCl, In64BitMode]>; |
| 182 } |
| 183 |
| 184 def : Pat<(X86call (i32 tglobaladdr:$dst)), |
| 185 (NACL_CG_CALL64pcrel32 tglobaladdr:$dst)>, |
| 186 Requires<[IsNaCl, In64BitMode]>; |
| 187 def : Pat<(X86call (i32 texternalsym:$dst)), |
| 188 (NACL_CG_CALL64pcrel32 texternalsym:$dst)>, |
| 189 Requires<[IsNaCl, In64BitMode]>; |
| 190 |
| 191 // Tail calls |
| 192 // Also needed due to the i64 / i32 pointer problem. |
| 193 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, |
| 194 isCodeGenOnly = 1 in |
| 195 let Uses = [RSP] in { |
| 196 |
| 197 def NACL_CG_TCRETURNdi64 : I<0, Pseudo, (outs), |
| 198 (ins i32imm_pcrel:$dst, i32imm:$offset), |
| 199 "#TC_RETURN $dst $offset", []>, |
| 200 Requires<[IsNaCl, In64BitMode]>; |
| 201 |
| 202 def NACL_CG_TAILJMPd64 : I<0, Pseudo, (outs), |
| 203 (ins i32imm_pcrel:$dst), |
| 204 "jmp\t$dst # TAILCALL", []>, |
| 205 Requires<[IsNaCl, In64BitMode]>; |
| 206 } |
| 207 |
| 208 def : Pat<(X86tcret (i32 tglobaladdr:$dst), imm:$off), |
| 209 (NACL_CG_TCRETURNdi64 tglobaladdr:$dst, imm:$off)>, |
| 210 Requires<[IsNaCl, In64BitMode]>; |
| 211 |
| 212 def : Pat<(X86tcret (i32 texternalsym:$dst), imm:$off), |
| 213 (NACL_CG_TCRETURNdi64 texternalsym:$dst, imm:$off)>, |
| 214 Requires<[IsNaCl, In64BitMode]>; |
| 215 |
| 216 // ELF TLS Support |
| 217 |
| 218 // These are lowered in X86NaClRewritePass. |
| 219 let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, |
| 220 FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, ST1, |
| 221 MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, |
| 222 XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, |
| 223 XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS], |
| 224 Uses = [RSP] in { |
| 225 def NACL_CG_GD_TLS_addr64 : I<0, Pseudo, (outs), (ins i32mem:$sym), "", |
| 226 [(X86tlsaddr tls32addr:$sym)]>, |
| 227 Requires<[IsNaCl, In64BitMode]>; |
| 228 def NACL_CG_LE_TLS_addr64 : I<0, Pseudo, (outs), (ins i32mem:$sym), "", |
| 229 [(X86tlsaddr_le tls32addr:$sym)]>, |
| 230 Requires<[IsNaCl, In64BitMode]>; |
| 231 def NACL_CG_IE_TLS_addr64 : I<0, Pseudo, (outs), (ins i32mem:$sym), "", |
| 232 [(X86tlsaddr_ie tls32addr:$sym)]>, |
| 233 Requires<[IsNaCl, In64BitMode]>; |
| 234 // For mtls-use-call. |
| 235 def NACL_CG_LE_TLS_addr32 : I<0, Pseudo, (outs), (ins i32mem:$sym), "", |
| 236 [(X86tlsaddr_le tls32addr:$sym)]>, |
| 237 Requires<[IsNaCl, Not64BitMode]>; |
| 238 def NACL_CG_IE_TLS_addr32 : I<0, Pseudo, (outs), (ins i32mem:$sym), "", |
| 239 [(X86tlsaddr_ie tls32addr:$sym)]>, |
| 240 Requires<[IsNaCl, Not64BitMode]>; |
| 241 } |
| 242 |
| 243 let usesCustomInserter = 1, Defs = [EFLAGS] in |
| 244 def NACL_CG_VAARG_64 : I<0, Pseudo, |
| 245 (outs GR32:$dst), |
| 246 (ins i8mem:$ap, i32imm:$size, i8imm:$mode, i32imm:$align), |
| 247 "#NACL_VAARG_64 $dst, $ap, $size, $mode, $align", |
| 248 [(set GR32:$dst, |
| 249 (X86vaarg64 addr:$ap, imm:$size, imm:$mode, imm:$align)), |
| 250 (implicit EFLAGS)]>, |
| 251 Requires<[IsNaCl, In64BitMode]>; |
OLD | NEW |