| Index: lib/Target/X86/X86InstrNaCl.td
|
| diff --git a/lib/Target/X86/X86InstrNaCl.td b/lib/Target/X86/X86InstrNaCl.td
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..2f35a784df1cb777efb5f7fc3bd4f33f3d2c3951
|
| --- /dev/null
|
| +++ b/lib/Target/X86/X86InstrNaCl.td
|
| @@ -0,0 +1,251 @@
|
| +//====- X86InstrNaCl.td - Describe NaCl Instructions ----*- tablegen -*-===//
|
| +//
|
| +// The LLVM Compiler Infrastructure
|
| +//
|
| +// This file is distributed under the University of Illinois Open Source
|
| +// License. See LICENSE.TXT for details.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +//
|
| +// This file describes the modifications to the X86 instruction set needed for
|
| +// Native Client code generation.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +
|
| +
|
| +//===----------------------------------------------------------------------===//
|
| +// NaCl specific DAG Nodes.
|
| +//
|
| +
|
| +//===----------------------------------------------------------------------===//
|
| +//
|
| +// Native Client Pseudo-Instructions
|
| +//
|
| +// These instructions implement the Native Client pseudo-instructions, such
|
| +// as nacljmp and naclasp.
|
| +//
|
| +// TableGen and MC consider these to be "real" instructions. They can be
|
| +// parsed by the AsmParser and emitted by the AsmStreamer as if they
|
| +// were just regular instructions. They are not marked "Pseudo" because
|
| +// this would imply isCodeGenOnly=1, which would stop them from being
|
| +// parsed by the assembler.
|
| +//
|
| +// These instructions cannot be encoded (written into an object file) by the
|
| +// MCCodeEmitter. Instead, during direct object emission, they get lowered to
|
| +// a sequence of streamer emits. (see X86InstrNaCl.cpp)
|
| +//
|
| +// These instructions should not be used in CodeGen. They have no pattern
|
| +// and lack CodeGen metadata. Instead, the X86NaClRewritePass should
|
| +// generate these instructions after CodeGen is finished.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +
|
| +
|
| +//===----------------------------------------------------------------------===//
|
| +// 32-bit Native Client Pseudo Instructions
|
| +//===----------------------------------------------------------------------===//
|
| +
|
| +class NaClPI32<dag outs, dag ins, string asm>
|
| + : I<0, CustomFrm, outs, ins, asm, []>, Requires<[IsNaCl, Not64BitMode]>;
|
| +
|
| +let isTerminator = 1, isReturn = 1, isBarrier = 1,
|
| + hasCtrlDep = 1, FPForm = SpecialFP, isAsmParserOnly = 1 in {
|
| + def NACL_RET32 : NaClPI32<(outs), (ins), "naclret">;
|
| + def NACL_RETI32 : NaClPI32<(outs), (ins i16imm:$amt), "naclreti\t$amt">;
|
| +}
|
| +
|
| +let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1,
|
| + isAsmParserOnly = 1 in {
|
| + def NACL_JMP32r : NaClPI32<(outs), (ins GR32:$dst), "nacljmp\t$dst">;
|
| +}
|
| +
|
| +let isCall = 1, isAsmParserOnly = 1 in {
|
| + def NACL_CALL32r : NaClPI32<(outs), (ins GR32:$dst),
|
| + "naclcall\t$dst">;
|
| +}
|
| +
|
| +
|
| +//===----------------------------------------------------------------------===//
|
| +// 64-bit Native Client Pseudo Instructions
|
| +//===----------------------------------------------------------------------===//
|
| +
|
| +class NaClPI64<dag outs, dag ins, string asm>
|
| + : I<0, CustomFrm, outs, ins, asm, []>, Requires<[IsNaCl, In64BitMode]>;
|
| +
|
| +let isTerminator = 1, isReturn = 1, isBarrier = 1,
|
| + hasCtrlDep = 1, FPForm = SpecialFP, isAsmParserOnly = 1 in {
|
| + def NACL_RET64 : NaClPI64<(outs), (ins), "naclret">;
|
| +}
|
| +
|
| +let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1,
|
| + isAsmParserOnly = 1 in {
|
| + def NACL_JMP64r : NaClPI64<(outs), (ins GR32:$dst, GR64:$rZP),
|
| + "nacljmp\t{$dst, $rZP|$rZP, $dst}">;
|
| + def NACL_JMP64z : NaClPI64<(outs), (ins GR32:$dst),
|
| + "nacljmp\t$dst">;
|
| +}
|
| +
|
| +
|
| +let isCall = 1, isAsmParserOnly = 1 in {
|
| + def NACL_CALL64d : NaClPI64<(outs), (ins i32imm_pcrel:$dst),
|
| + "call{q}\t$dst">;
|
| + def NACL_CALL64r : NaClPI64<(outs), (ins GR32:$dst, GR64:$rZP),
|
| + "naclcall\t$dst,$rZP">;
|
| +}
|
| +
|
| +let Defs = [RSP, EFLAGS], Uses = [RSP], isAsmParserOnly = 1 in {
|
| + def NACL_ASPi8 : NaClPI64<(outs), (ins i64i8imm:$off, GR64:$rZP),
|
| + "naclasp{q}\t{$off, $rZP|$rZP, $off}">;
|
| +
|
| + def NACL_ASPi32: NaClPI64<(outs), (ins i64i32imm:$off, GR64:$rZP),
|
| + "naclasp{q}\t{$off, $rZP|$rZP, $off}">;
|
| +
|
| + def NACL_SSPi8 : NaClPI64<(outs), (ins i64i8imm:$off, GR64:$rZP),
|
| + "naclssp{q}\t{$off, $rZP|$rZP, $off}">;
|
| +
|
| + def NACL_SSPi32: NaClPI64<(outs), (ins i64i32imm:$off, GR64:$rZP),
|
| + "naclssp{q}\t{$off, $rZP|$rZP, $off}">;
|
| +
|
| + def NACL_ANDSPi8: NaClPI64<(outs), (ins i64i8imm:$off, GR64:$rZP),
|
| + "naclandsp{q}\t{$off, $rZP|$rZP, $off}">;
|
| +
|
| + def NACL_ANDSPi32: NaClPI64<(outs), (ins i64i32imm:$off, GR64:$rZP),
|
| + "naclandsp{q}\t{$off, $rZP|$rZP, $off}">;
|
| +}
|
| +
|
| +let Defs = [RSP], Uses = [RBP], isAsmParserOnly = 1 in {
|
| + def NACL_SPADJi32 : NaClPI64<(outs), (ins i64i32imm:$off, GR64:$rZP),
|
| + "naclspadj\t{$off, $rZP|$rZP, $off}">;
|
| +}
|
| +
|
| +let Defs = [RSP], isAsmParserOnly = 1 in {
|
| + def NACL_RESTSPr : NaClPI64<(outs), (ins GR32:$src, GR64:$rZP),
|
| + "naclrestsp_noflags\t{$src, $rZP|$rZP, $src}">;
|
| + def NACL_RESTSPm : NaClPI64<(outs), (ins i32mem:$src, GR64:$rZP),
|
| + "naclrestsp_noflags\t{$src, $rZP|$rZP, $src}">;
|
| + def NACL_RESTSPrz : NaClPI64<(outs), (ins GR32:$src),
|
| + "naclrestsp_noflags\t$src">;
|
| +}
|
| +
|
| +def : MnemonicAlias<"naclrestsp", "naclrestsp_noflags">;
|
| +
|
| +let Defs = [RBP], isAsmParserOnly = 1 in {
|
| + def NACL_RESTBPr : NaClPI64<(outs), (ins GR32:$src, GR64:$rZP),
|
| + "naclrestbp\t{$src, $rZP|$rZP, $src}">;
|
| + def NACL_RESTBPm : NaClPI64<(outs), (ins i32mem:$src, GR64:$rZP),
|
| + "naclrestbp\t{$src, $rZP|$rZP, $src}">;
|
| + def NACL_RESTBPrz : NaClPI64<(outs), (ins GR32:$src),
|
| + "naclrestbp\t$src">;
|
| +}
|
| +
|
| +//===----------------------------------------------------------------------===//
|
| +//
|
| +// Code Generator Instructions (isCodeGenOnly == 1)
|
| +//
|
| +// These instructions exists to make CodeGen work with Native Client's
|
| +// modifications.
|
| +//
|
| +// Many of these instructions exist because of limitations in CodeGen
|
| +// or TableGen, and may become unnecessary in the future.
|
| +//===----------------------------------------------------------------------===//
|
| +
|
| +//===----------------------------------------------------------------------===//
|
| +//
|
| +// CodeGen 64-bit
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +
|
| +
|
| +// Because pointers are 32-bit on X86-64 Native Client, we need to
|
| +// produce new versions of the JMP64/CALL64 instructions which can accept
|
| +// addresses which are i32 instead of i64.
|
| +//
|
| +// Indirect calls have been changed to zero extend i32 to i64, so
|
| +// we don't need a NaCl-specific CALL64r. We could possibly do the same for
|
| +// indirect branches (switch jump tables) and direct calls.
|
| +
|
| +let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
|
| + def NACL_CG_JMP64r : I<0, Pseudo, (outs), (ins GR32:$dst),
|
| + "nacljmp\t$dst",
|
| + [(brind GR32:$dst)]>,
|
| + Requires<[IsNaCl, In64BitMode]>;
|
| +}
|
| +
|
| +// RSP is marked as a use to prevent stack-pointer assignments that appear
|
| +// immediately before calls from potentially appearing dead. Uses for argument
|
| +// registers are added manually.
|
| +let isCall = 1, Uses = [RSP] in {
|
| + def NACL_CG_CALL64pcrel32 : I<0, Pseudo, (outs),
|
| + (ins i32imm_pcrel:$dst),
|
| + "call{q}\t$dst", []>,
|
| + Requires<[IsNaCl, In64BitMode]>;
|
| +}
|
| +
|
| +def : Pat<(X86call (i32 tglobaladdr:$dst)),
|
| + (NACL_CG_CALL64pcrel32 tglobaladdr:$dst)>,
|
| + Requires<[IsNaCl, In64BitMode]>;
|
| +def : Pat<(X86call (i32 texternalsym:$dst)),
|
| + (NACL_CG_CALL64pcrel32 texternalsym:$dst)>,
|
| + Requires<[IsNaCl, In64BitMode]>;
|
| +
|
| +// Tail calls
|
| +// Also needed due to the i64 / i32 pointer problem.
|
| +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
|
| + isCodeGenOnly = 1 in
|
| + let Uses = [RSP] in {
|
| +
|
| + def NACL_CG_TCRETURNdi64 : I<0, Pseudo, (outs),
|
| + (ins i32imm_pcrel:$dst, i32imm:$offset),
|
| + "#TC_RETURN $dst $offset", []>,
|
| + Requires<[IsNaCl, In64BitMode]>;
|
| +
|
| + def NACL_CG_TAILJMPd64 : I<0, Pseudo, (outs),
|
| + (ins i32imm_pcrel:$dst),
|
| + "jmp\t$dst # TAILCALL", []>,
|
| + Requires<[IsNaCl, In64BitMode]>;
|
| +}
|
| +
|
| +def : Pat<(X86tcret (i32 tglobaladdr:$dst), imm:$off),
|
| + (NACL_CG_TCRETURNdi64 tglobaladdr:$dst, imm:$off)>,
|
| + Requires<[IsNaCl, In64BitMode]>;
|
| +
|
| +def : Pat<(X86tcret (i32 texternalsym:$dst), imm:$off),
|
| + (NACL_CG_TCRETURNdi64 texternalsym:$dst, imm:$off)>,
|
| + Requires<[IsNaCl, In64BitMode]>;
|
| +
|
| +// ELF TLS Support
|
| +
|
| +// These are lowered in X86NaClRewritePass.
|
| +let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
|
| + FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, ST1,
|
| + MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
|
| + XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
|
| + XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
|
| + Uses = [RSP] in {
|
| +def NACL_CG_GD_TLS_addr64 : I<0, Pseudo, (outs), (ins i32mem:$sym), "",
|
| + [(X86tlsaddr tls32addr:$sym)]>,
|
| + Requires<[IsNaCl, In64BitMode]>;
|
| +def NACL_CG_LE_TLS_addr64 : I<0, Pseudo, (outs), (ins i32mem:$sym), "",
|
| + [(X86tlsaddr_le tls32addr:$sym)]>,
|
| + Requires<[IsNaCl, In64BitMode]>;
|
| +def NACL_CG_IE_TLS_addr64 : I<0, Pseudo, (outs), (ins i32mem:$sym), "",
|
| + [(X86tlsaddr_ie tls32addr:$sym)]>,
|
| + Requires<[IsNaCl, In64BitMode]>;
|
| +// For mtls-use-call.
|
| +def NACL_CG_LE_TLS_addr32 : I<0, Pseudo, (outs), (ins i32mem:$sym), "",
|
| + [(X86tlsaddr_le tls32addr:$sym)]>,
|
| + Requires<[IsNaCl, Not64BitMode]>;
|
| +def NACL_CG_IE_TLS_addr32 : I<0, Pseudo, (outs), (ins i32mem:$sym), "",
|
| + [(X86tlsaddr_ie tls32addr:$sym)]>,
|
| + Requires<[IsNaCl, Not64BitMode]>;
|
| +}
|
| +
|
| +let usesCustomInserter = 1, Defs = [EFLAGS] in
|
| +def NACL_CG_VAARG_64 : I<0, Pseudo,
|
| + (outs GR32:$dst),
|
| + (ins i8mem:$ap, i32imm:$size, i8imm:$mode, i32imm:$align),
|
| + "#NACL_VAARG_64 $dst, $ap, $size, $mode, $align",
|
| + [(set GR32:$dst,
|
| + (X86vaarg64 addr:$ap, imm:$size, imm:$mode, imm:$align)),
|
| + (implicit EFLAGS)]>,
|
| + Requires<[IsNaCl, In64BitMode]>;
|
|
|