X86MCCodeEmitter.cpp revision 251662
1234353Sdim//===-- X86MCCodeEmitter.cpp - Convert X86 code to machine code -----------===// 2226584Sdim// 3226584Sdim// The LLVM Compiler Infrastructure 4226584Sdim// 5226584Sdim// This file is distributed under the University of Illinois Open Source 6226584Sdim// License. See LICENSE.TXT for details. 7226584Sdim// 8226584Sdim//===----------------------------------------------------------------------===// 9226584Sdim// 10226584Sdim// This file implements the X86MCCodeEmitter class. 11226584Sdim// 12226584Sdim//===----------------------------------------------------------------------===// 13226584Sdim 14226584Sdim#define DEBUG_TYPE "mccodeemitter" 15226584Sdim#include "MCTargetDesc/X86MCTargetDesc.h" 16226584Sdim#include "MCTargetDesc/X86BaseInfo.h" 17226584Sdim#include "MCTargetDesc/X86FixupKinds.h" 18226584Sdim#include "llvm/MC/MCCodeEmitter.h" 19243830Sdim#include "llvm/MC/MCContext.h" 20226584Sdim#include "llvm/MC/MCExpr.h" 21226584Sdim#include "llvm/MC/MCInst.h" 22226584Sdim#include "llvm/MC/MCInstrInfo.h" 23226584Sdim#include "llvm/MC/MCRegisterInfo.h" 24226584Sdim#include "llvm/MC/MCSubtargetInfo.h" 25226584Sdim#include "llvm/MC/MCSymbol.h" 26226584Sdim#include "llvm/Support/raw_ostream.h" 27226584Sdim 28226584Sdimusing namespace llvm; 29226584Sdim 30226584Sdimnamespace { 31226584Sdimclass X86MCCodeEmitter : public MCCodeEmitter { 32243830Sdim X86MCCodeEmitter(const X86MCCodeEmitter &) LLVM_DELETED_FUNCTION; 33243830Sdim void operator=(const X86MCCodeEmitter &) LLVM_DELETED_FUNCTION; 34226584Sdim const MCInstrInfo &MCII; 35226584Sdim const MCSubtargetInfo &STI; 36226584Sdim MCContext &Ctx; 37226584Sdimpublic: 38226584Sdim X86MCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti, 39226584Sdim MCContext &ctx) 40226584Sdim : MCII(mcii), STI(sti), Ctx(ctx) { 41226584Sdim } 42226584Sdim 43226584Sdim ~X86MCCodeEmitter() {} 44226584Sdim 45226584Sdim bool is64BitMode() const { 46226584Sdim // FIXME: Can tablegen auto-generate this? 47226584Sdim return (STI.getFeatureBits() & X86::Mode64Bit) != 0; 48226584Sdim } 49226584Sdim 50234353Sdim bool is32BitMode() const { 51234353Sdim // FIXME: Can tablegen auto-generate this? 52234353Sdim return (STI.getFeatureBits() & X86::Mode64Bit) == 0; 53234353Sdim } 54234353Sdim 55243830Sdim unsigned GetX86RegNum(const MCOperand &MO) const { 56243830Sdim return Ctx.getRegisterInfo().getEncodingValue(MO.getReg()) & 0x7; 57226584Sdim } 58226584Sdim 59226584Sdim // On regular x86, both XMM0-XMM7 and XMM8-XMM15 are encoded in the range 60226584Sdim // 0-7 and the difference between the 2 groups is given by the REX prefix. 61226584Sdim // In the VEX prefix, registers are seen sequencially from 0-15 and encoded 62226584Sdim // in 1's complement form, example: 63226584Sdim // 64226584Sdim // ModRM field => XMM9 => 1 65226584Sdim // VEX.VVVV => XMM9 => ~9 66226584Sdim // 67226584Sdim // See table 4-35 of Intel AVX Programming Reference for details. 68243830Sdim unsigned char getVEXRegisterEncoding(const MCInst &MI, 69243830Sdim unsigned OpNum) const { 70226584Sdim unsigned SrcReg = MI.getOperand(OpNum).getReg(); 71226584Sdim unsigned SrcRegNum = GetX86RegNum(MI.getOperand(OpNum)); 72234353Sdim if (X86II::isX86_64ExtendedReg(SrcReg)) 73234353Sdim SrcRegNum |= 8; 74226584Sdim 75226584Sdim // The registers represented through VEX_VVVV should 76226584Sdim // be encoded in 1's complement form. 77226584Sdim return (~SrcRegNum) & 0xf; 78226584Sdim } 79226584Sdim 80226584Sdim void EmitByte(unsigned char C, unsigned &CurByte, raw_ostream &OS) const { 81226584Sdim OS << (char)C; 82226584Sdim ++CurByte; 83226584Sdim } 84226584Sdim 85226584Sdim void EmitConstant(uint64_t Val, unsigned Size, unsigned &CurByte, 86226584Sdim raw_ostream &OS) const { 87226584Sdim // Output the constant in little endian byte order. 88226584Sdim for (unsigned i = 0; i != Size; ++i) { 89226584Sdim EmitByte(Val & 255, CurByte, OS); 90226584Sdim Val >>= 8; 91226584Sdim } 92226584Sdim } 93226584Sdim 94234353Sdim void EmitImmediate(const MCOperand &Disp, SMLoc Loc, 95226584Sdim unsigned ImmSize, MCFixupKind FixupKind, 96226584Sdim unsigned &CurByte, raw_ostream &OS, 97226584Sdim SmallVectorImpl<MCFixup> &Fixups, 98226584Sdim int ImmOffset = 0) const; 99226584Sdim 100226584Sdim inline static unsigned char ModRMByte(unsigned Mod, unsigned RegOpcode, 101226584Sdim unsigned RM) { 102226584Sdim assert(Mod < 4 && RegOpcode < 8 && RM < 8 && "ModRM Fields out of range!"); 103226584Sdim return RM | (RegOpcode << 3) | (Mod << 6); 104226584Sdim } 105226584Sdim 106226584Sdim void EmitRegModRMByte(const MCOperand &ModRMReg, unsigned RegOpcodeFld, 107226584Sdim unsigned &CurByte, raw_ostream &OS) const { 108226584Sdim EmitByte(ModRMByte(3, RegOpcodeFld, GetX86RegNum(ModRMReg)), CurByte, OS); 109226584Sdim } 110226584Sdim 111226584Sdim void EmitSIBByte(unsigned SS, unsigned Index, unsigned Base, 112226584Sdim unsigned &CurByte, raw_ostream &OS) const { 113226584Sdim // SIB byte is in the same format as the ModRMByte. 114226584Sdim EmitByte(ModRMByte(SS, Index, Base), CurByte, OS); 115226584Sdim } 116226584Sdim 117226584Sdim 118226584Sdim void EmitMemModRMByte(const MCInst &MI, unsigned Op, 119226584Sdim unsigned RegOpcodeField, 120226584Sdim uint64_t TSFlags, unsigned &CurByte, raw_ostream &OS, 121226584Sdim SmallVectorImpl<MCFixup> &Fixups) const; 122226584Sdim 123226584Sdim void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 124226584Sdim SmallVectorImpl<MCFixup> &Fixups) const; 125226584Sdim 126226584Sdim void EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand, 127226584Sdim const MCInst &MI, const MCInstrDesc &Desc, 128226584Sdim raw_ostream &OS) const; 129226584Sdim 130226584Sdim void EmitSegmentOverridePrefix(uint64_t TSFlags, unsigned &CurByte, 131226584Sdim int MemOperand, const MCInst &MI, 132226584Sdim raw_ostream &OS) const; 133226584Sdim 134226584Sdim void EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand, 135226584Sdim const MCInst &MI, const MCInstrDesc &Desc, 136226584Sdim raw_ostream &OS) const; 137226584Sdim}; 138226584Sdim 139226584Sdim} // end anonymous namespace 140226584Sdim 141226584Sdim 142226584SdimMCCodeEmitter *llvm::createX86MCCodeEmitter(const MCInstrInfo &MCII, 143239462Sdim const MCRegisterInfo &MRI, 144226584Sdim const MCSubtargetInfo &STI, 145226584Sdim MCContext &Ctx) { 146226584Sdim return new X86MCCodeEmitter(MCII, STI, Ctx); 147226584Sdim} 148226584Sdim 149226584Sdim/// isDisp8 - Return true if this signed displacement fits in a 8-bit 150226584Sdim/// sign-extended field. 151226584Sdimstatic bool isDisp8(int Value) { 152226584Sdim return Value == (signed char)Value; 153226584Sdim} 154226584Sdim 155226584Sdim/// getImmFixupKind - Return the appropriate fixup kind to use for an immediate 156226584Sdim/// in an instruction with the specified TSFlags. 157226584Sdimstatic MCFixupKind getImmFixupKind(uint64_t TSFlags) { 158226584Sdim unsigned Size = X86II::getSizeOfImm(TSFlags); 159226584Sdim bool isPCRel = X86II::isImmPCRel(TSFlags); 160226584Sdim 161226584Sdim return MCFixup::getKindForSize(Size, isPCRel); 162226584Sdim} 163226584Sdim 164234353Sdim/// Is32BitMemOperand - Return true if the specified instruction has 165234353Sdim/// a 32-bit memory operand. Op specifies the operand # of the memoperand. 166226584Sdimstatic bool Is32BitMemOperand(const MCInst &MI, unsigned Op) { 167226584Sdim const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg); 168226584Sdim const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); 169226584Sdim 170226584Sdim if ((BaseReg.getReg() != 0 && 171226584Sdim X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg.getReg())) || 172226584Sdim (IndexReg.getReg() != 0 && 173226584Sdim X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg.getReg()))) 174226584Sdim return true; 175226584Sdim return false; 176226584Sdim} 177226584Sdim 178234353Sdim/// Is64BitMemOperand - Return true if the specified instruction has 179234353Sdim/// a 64-bit memory operand. Op specifies the operand # of the memoperand. 180234353Sdim#ifndef NDEBUG 181234353Sdimstatic bool Is64BitMemOperand(const MCInst &MI, unsigned Op) { 182234353Sdim const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg); 183234353Sdim const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); 184234353Sdim 185234353Sdim if ((BaseReg.getReg() != 0 && 186234353Sdim X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg.getReg())) || 187234353Sdim (IndexReg.getReg() != 0 && 188234353Sdim X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg.getReg()))) 189234353Sdim return true; 190234353Sdim return false; 191234353Sdim} 192234353Sdim#endif 193234353Sdim 194234353Sdim/// Is16BitMemOperand - Return true if the specified instruction has 195234353Sdim/// a 16-bit memory operand. Op specifies the operand # of the memoperand. 196234353Sdimstatic bool Is16BitMemOperand(const MCInst &MI, unsigned Op) { 197234353Sdim const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg); 198234353Sdim const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); 199234353Sdim 200234353Sdim if ((BaseReg.getReg() != 0 && 201234353Sdim X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg.getReg())) || 202234353Sdim (IndexReg.getReg() != 0 && 203234353Sdim X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg.getReg()))) 204234353Sdim return true; 205234353Sdim return false; 206234353Sdim} 207234353Sdim 208234353Sdim/// StartsWithGlobalOffsetTable - Check if this expression starts with 209234353Sdim/// _GLOBAL_OFFSET_TABLE_ and if it is of the form 210234353Sdim/// _GLOBAL_OFFSET_TABLE_-symbol. This is needed to support PIC on ELF 211234353Sdim/// i386 as _GLOBAL_OFFSET_TABLE_ is magical. We check only simple case that 212226584Sdim/// are know to be used: _GLOBAL_OFFSET_TABLE_ by itself or at the start 213226584Sdim/// of a binary expression. 214234353Sdimenum GlobalOffsetTableExprKind { 215234353Sdim GOT_None, 216234353Sdim GOT_Normal, 217234353Sdim GOT_SymDiff 218234353Sdim}; 219234353Sdimstatic GlobalOffsetTableExprKind 220234353SdimStartsWithGlobalOffsetTable(const MCExpr *Expr) { 221234353Sdim const MCExpr *RHS = 0; 222226584Sdim if (Expr->getKind() == MCExpr::Binary) { 223226584Sdim const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(Expr); 224226584Sdim Expr = BE->getLHS(); 225234353Sdim RHS = BE->getRHS(); 226226584Sdim } 227226584Sdim 228226584Sdim if (Expr->getKind() != MCExpr::SymbolRef) 229234353Sdim return GOT_None; 230226584Sdim 231226584Sdim const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 232226584Sdim const MCSymbol &S = Ref->getSymbol(); 233234353Sdim if (S.getName() != "_GLOBAL_OFFSET_TABLE_") 234234353Sdim return GOT_None; 235234353Sdim if (RHS && RHS->getKind() == MCExpr::SymbolRef) 236234353Sdim return GOT_SymDiff; 237234353Sdim return GOT_Normal; 238226584Sdim} 239226584Sdim 240251662Sdimstatic bool HasSecRelSymbolRef(const MCExpr *Expr) { 241251662Sdim if (Expr->getKind() == MCExpr::SymbolRef) { 242251662Sdim const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 243251662Sdim return Ref->getKind() == MCSymbolRefExpr::VK_SECREL; 244251662Sdim } 245251662Sdim return false; 246251662Sdim} 247251662Sdim 248226584Sdimvoid X86MCCodeEmitter:: 249234353SdimEmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size, 250234353Sdim MCFixupKind FixupKind, unsigned &CurByte, raw_ostream &OS, 251226584Sdim SmallVectorImpl<MCFixup> &Fixups, int ImmOffset) const { 252226584Sdim const MCExpr *Expr = NULL; 253226584Sdim if (DispOp.isImm()) { 254226584Sdim // If this is a simple integer displacement that doesn't require a 255226584Sdim // relocation, emit it now. 256226584Sdim if (FixupKind != FK_PCRel_1 && 257226584Sdim FixupKind != FK_PCRel_2 && 258226584Sdim FixupKind != FK_PCRel_4) { 259226584Sdim EmitConstant(DispOp.getImm()+ImmOffset, Size, CurByte, OS); 260226584Sdim return; 261226584Sdim } 262226584Sdim Expr = MCConstantExpr::Create(DispOp.getImm(), Ctx); 263226584Sdim } else { 264226584Sdim Expr = DispOp.getExpr(); 265226584Sdim } 266226584Sdim 267226584Sdim // If we have an immoffset, add it to the expression. 268226584Sdim if ((FixupKind == FK_Data_4 || 269234353Sdim FixupKind == FK_Data_8 || 270234353Sdim FixupKind == MCFixupKind(X86::reloc_signed_4byte))) { 271234353Sdim GlobalOffsetTableExprKind Kind = StartsWithGlobalOffsetTable(Expr); 272234353Sdim if (Kind != GOT_None) { 273234353Sdim assert(ImmOffset == 0); 274226584Sdim 275234353Sdim FixupKind = MCFixupKind(X86::reloc_global_offset_table); 276234353Sdim if (Kind == GOT_Normal) 277234353Sdim ImmOffset = CurByte; 278234353Sdim } else if (Expr->getKind() == MCExpr::SymbolRef) { 279251662Sdim if (HasSecRelSymbolRef(Expr)) { 280234353Sdim FixupKind = MCFixupKind(FK_SecRel_4); 281234353Sdim } 282251662Sdim } else if (Expr->getKind() == MCExpr::Binary) { 283251662Sdim const MCBinaryExpr *Bin = static_cast<const MCBinaryExpr*>(Expr); 284251662Sdim if (HasSecRelSymbolRef(Bin->getLHS()) 285251662Sdim || HasSecRelSymbolRef(Bin->getRHS())) { 286251662Sdim FixupKind = MCFixupKind(FK_SecRel_4); 287251662Sdim } 288234353Sdim } 289226584Sdim } 290226584Sdim 291226584Sdim // If the fixup is pc-relative, we need to bias the value to be relative to 292226584Sdim // the start of the field, not the end of the field. 293226584Sdim if (FixupKind == FK_PCRel_4 || 294226584Sdim FixupKind == MCFixupKind(X86::reloc_riprel_4byte) || 295226584Sdim FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load)) 296226584Sdim ImmOffset -= 4; 297226584Sdim if (FixupKind == FK_PCRel_2) 298226584Sdim ImmOffset -= 2; 299226584Sdim if (FixupKind == FK_PCRel_1) 300226584Sdim ImmOffset -= 1; 301226584Sdim 302226584Sdim if (ImmOffset) 303226584Sdim Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(ImmOffset, Ctx), 304226584Sdim Ctx); 305226584Sdim 306226584Sdim // Emit a symbolic constant as a fixup and 4 zeros. 307234353Sdim Fixups.push_back(MCFixup::Create(CurByte, Expr, FixupKind, Loc)); 308226584Sdim EmitConstant(0, Size, CurByte, OS); 309226584Sdim} 310226584Sdim 311226584Sdimvoid X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, 312226584Sdim unsigned RegOpcodeField, 313226584Sdim uint64_t TSFlags, unsigned &CurByte, 314226584Sdim raw_ostream &OS, 315226584Sdim SmallVectorImpl<MCFixup> &Fixups) const{ 316226584Sdim const MCOperand &Disp = MI.getOperand(Op+X86::AddrDisp); 317226584Sdim const MCOperand &Base = MI.getOperand(Op+X86::AddrBaseReg); 318226584Sdim const MCOperand &Scale = MI.getOperand(Op+X86::AddrScaleAmt); 319226584Sdim const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); 320226584Sdim unsigned BaseReg = Base.getReg(); 321226584Sdim 322226584Sdim // Handle %rip relative addressing. 323226584Sdim if (BaseReg == X86::RIP) { // [disp32+RIP] in X86-64 mode 324226584Sdim assert(is64BitMode() && "Rip-relative addressing requires 64-bit mode"); 325226584Sdim assert(IndexReg.getReg() == 0 && "Invalid rip-relative address"); 326226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS); 327226584Sdim 328226584Sdim unsigned FixupKind = X86::reloc_riprel_4byte; 329226584Sdim 330226584Sdim // movq loads are handled with a special relocation form which allows the 331226584Sdim // linker to eliminate some loads for GOT references which end up in the 332226584Sdim // same linkage unit. 333226584Sdim if (MI.getOpcode() == X86::MOV64rm) 334226584Sdim FixupKind = X86::reloc_riprel_4byte_movq_load; 335226584Sdim 336226584Sdim // rip-relative addressing is actually relative to the *next* instruction. 337226584Sdim // Since an immediate can follow the mod/rm byte for an instruction, this 338226584Sdim // means that we need to bias the immediate field of the instruction with 339226584Sdim // the size of the immediate field. If we have this case, add it into the 340226584Sdim // expression to emit. 341226584Sdim int ImmSize = X86II::hasImm(TSFlags) ? X86II::getSizeOfImm(TSFlags) : 0; 342226584Sdim 343234353Sdim EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind), 344226584Sdim CurByte, OS, Fixups, -ImmSize); 345226584Sdim return; 346226584Sdim } 347226584Sdim 348226584Sdim unsigned BaseRegNo = BaseReg ? GetX86RegNum(Base) : -1U; 349226584Sdim 350226584Sdim // Determine whether a SIB byte is needed. 351226584Sdim // If no BaseReg, issue a RIP relative instruction only if the MCE can 352226584Sdim // resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table 353226584Sdim // 2-7) and absolute references. 354226584Sdim 355226584Sdim if (// The SIB byte must be used if there is an index register. 356226584Sdim IndexReg.getReg() == 0 && 357226584Sdim // The SIB byte must be used if the base is ESP/RSP/R12, all of which 358226584Sdim // encode to an R/M value of 4, which indicates that a SIB byte is 359226584Sdim // present. 360226584Sdim BaseRegNo != N86::ESP && 361226584Sdim // If there is no base register and we're in 64-bit mode, we need a SIB 362226584Sdim // byte to emit an addr that is just 'disp32' (the non-RIP relative form). 363226584Sdim (!is64BitMode() || BaseReg != 0)) { 364226584Sdim 365226584Sdim if (BaseReg == 0) { // [disp32] in X86-32 mode 366226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS); 367234353Sdim EmitImmediate(Disp, MI.getLoc(), 4, FK_Data_4, CurByte, OS, Fixups); 368226584Sdim return; 369226584Sdim } 370226584Sdim 371226584Sdim // If the base is not EBP/ESP and there is no displacement, use simple 372226584Sdim // indirect register encoding, this handles addresses like [EAX]. The 373226584Sdim // encoding for [EBP] with no displacement means [disp32] so we handle it 374226584Sdim // by emitting a displacement of 0 below. 375226584Sdim if (Disp.isImm() && Disp.getImm() == 0 && BaseRegNo != N86::EBP) { 376226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, BaseRegNo), CurByte, OS); 377226584Sdim return; 378226584Sdim } 379226584Sdim 380226584Sdim // Otherwise, if the displacement fits in a byte, encode as [REG+disp8]. 381226584Sdim if (Disp.isImm() && isDisp8(Disp.getImm())) { 382226584Sdim EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS); 383234353Sdim EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups); 384226584Sdim return; 385226584Sdim } 386226584Sdim 387226584Sdim // Otherwise, emit the most general non-SIB encoding: [REG+disp32] 388226584Sdim EmitByte(ModRMByte(2, RegOpcodeField, BaseRegNo), CurByte, OS); 389234353Sdim EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte), CurByte, OS, 390226584Sdim Fixups); 391226584Sdim return; 392226584Sdim } 393226584Sdim 394226584Sdim // We need a SIB byte, so start by outputting the ModR/M byte first 395226584Sdim assert(IndexReg.getReg() != X86::ESP && 396226584Sdim IndexReg.getReg() != X86::RSP && "Cannot use ESP as index reg!"); 397226584Sdim 398226584Sdim bool ForceDisp32 = false; 399226584Sdim bool ForceDisp8 = false; 400226584Sdim if (BaseReg == 0) { 401226584Sdim // If there is no base register, we emit the special case SIB byte with 402226584Sdim // MOD=0, BASE=5, to JUST get the index, scale, and displacement. 403226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, 4), CurByte, OS); 404226584Sdim ForceDisp32 = true; 405226584Sdim } else if (!Disp.isImm()) { 406226584Sdim // Emit the normal disp32 encoding. 407226584Sdim EmitByte(ModRMByte(2, RegOpcodeField, 4), CurByte, OS); 408226584Sdim ForceDisp32 = true; 409226584Sdim } else if (Disp.getImm() == 0 && 410226584Sdim // Base reg can't be anything that ends up with '5' as the base 411226584Sdim // reg, it is the magic [*] nomenclature that indicates no base. 412226584Sdim BaseRegNo != N86::EBP) { 413226584Sdim // Emit no displacement ModR/M byte 414226584Sdim EmitByte(ModRMByte(0, RegOpcodeField, 4), CurByte, OS); 415226584Sdim } else if (isDisp8(Disp.getImm())) { 416226584Sdim // Emit the disp8 encoding. 417226584Sdim EmitByte(ModRMByte(1, RegOpcodeField, 4), CurByte, OS); 418226584Sdim ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP 419226584Sdim } else { 420226584Sdim // Emit the normal disp32 encoding. 421226584Sdim EmitByte(ModRMByte(2, RegOpcodeField, 4), CurByte, OS); 422226584Sdim } 423226584Sdim 424226584Sdim // Calculate what the SS field value should be... 425226584Sdim static const unsigned SSTable[] = { ~0U, 0, 1, ~0U, 2, ~0U, ~0U, ~0U, 3 }; 426226584Sdim unsigned SS = SSTable[Scale.getImm()]; 427226584Sdim 428226584Sdim if (BaseReg == 0) { 429226584Sdim // Handle the SIB byte for the case where there is no base, see Intel 430226584Sdim // Manual 2A, table 2-7. The displacement has already been output. 431226584Sdim unsigned IndexRegNo; 432226584Sdim if (IndexReg.getReg()) 433226584Sdim IndexRegNo = GetX86RegNum(IndexReg); 434226584Sdim else // Examples: [ESP+1*<noreg>+4] or [scaled idx]+disp32 (MOD=0,BASE=5) 435226584Sdim IndexRegNo = 4; 436226584Sdim EmitSIBByte(SS, IndexRegNo, 5, CurByte, OS); 437226584Sdim } else { 438226584Sdim unsigned IndexRegNo; 439226584Sdim if (IndexReg.getReg()) 440226584Sdim IndexRegNo = GetX86RegNum(IndexReg); 441226584Sdim else 442226584Sdim IndexRegNo = 4; // For example [ESP+1*<noreg>+4] 443226584Sdim EmitSIBByte(SS, IndexRegNo, GetX86RegNum(Base), CurByte, OS); 444226584Sdim } 445226584Sdim 446226584Sdim // Do we need to output a displacement? 447226584Sdim if (ForceDisp8) 448234353Sdim EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups); 449226584Sdim else if (ForceDisp32 || Disp.getImm() != 0) 450234353Sdim EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte), 451234353Sdim CurByte, OS, Fixups); 452226584Sdim} 453226584Sdim 454226584Sdim/// EmitVEXOpcodePrefix - AVX instructions are encoded using a opcode prefix 455226584Sdim/// called VEX. 456226584Sdimvoid X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, 457226584Sdim int MemOperand, const MCInst &MI, 458226584Sdim const MCInstrDesc &Desc, 459226584Sdim raw_ostream &OS) const { 460234353Sdim bool HasVEX_4V = (TSFlags >> X86II::VEXShift) & X86II::VEX_4V; 461234353Sdim bool HasVEX_4VOp3 = (TSFlags >> X86II::VEXShift) & X86II::VEX_4VOp3; 462249423Sdim bool HasMemOp4 = (TSFlags >> X86II::VEXShift) & X86II::MemOp4; 463226584Sdim 464226584Sdim // VEX_R: opcode externsion equivalent to REX.R in 465226584Sdim // 1's complement (inverted) form 466226584Sdim // 467226584Sdim // 1: Same as REX_R=0 (must be 1 in 32-bit mode) 468226584Sdim // 0: Same as REX_R=1 (64 bit mode only) 469226584Sdim // 470226584Sdim unsigned char VEX_R = 0x1; 471226584Sdim 472226584Sdim // VEX_X: equivalent to REX.X, only used when a 473226584Sdim // register is used for index in SIB Byte. 474226584Sdim // 475226584Sdim // 1: Same as REX.X=0 (must be 1 in 32-bit mode) 476226584Sdim // 0: Same as REX.X=1 (64-bit mode only) 477226584Sdim unsigned char VEX_X = 0x1; 478226584Sdim 479226584Sdim // VEX_B: 480226584Sdim // 481226584Sdim // 1: Same as REX_B=0 (ignored in 32-bit mode) 482226584Sdim // 0: Same as REX_B=1 (64 bit mode only) 483226584Sdim // 484226584Sdim unsigned char VEX_B = 0x1; 485226584Sdim 486226584Sdim // VEX_W: opcode specific (use like REX.W, or used for 487226584Sdim // opcode extension, or ignored, depending on the opcode byte) 488226584Sdim unsigned char VEX_W = 0; 489226584Sdim 490234353Sdim // XOP: Use XOP prefix byte 0x8f instead of VEX. 491234353Sdim unsigned char XOP = 0; 492234353Sdim 493226584Sdim // VEX_5M (VEX m-mmmmm field): 494226584Sdim // 495226584Sdim // 0b00000: Reserved for future use 496226584Sdim // 0b00001: implied 0F leading opcode 497226584Sdim // 0b00010: implied 0F 38 leading opcode bytes 498226584Sdim // 0b00011: implied 0F 3A leading opcode bytes 499226584Sdim // 0b00100-0b11111: Reserved for future use 500234353Sdim // 0b01000: XOP map select - 08h instructions with imm byte 501234353Sdim // 0b10001: XOP map select - 09h instructions with no imm byte 502226584Sdim unsigned char VEX_5M = 0x1; 503226584Sdim 504226584Sdim // VEX_4V (VEX vvvv field): a register specifier 505226584Sdim // (in 1's complement form) or 1111 if unused. 506226584Sdim unsigned char VEX_4V = 0xf; 507226584Sdim 508226584Sdim // VEX_L (Vector Length): 509226584Sdim // 510226584Sdim // 0: scalar or 128-bit vector 511226584Sdim // 1: 256-bit vector 512226584Sdim // 513226584Sdim unsigned char VEX_L = 0; 514226584Sdim 515226584Sdim // VEX_PP: opcode extension providing equivalent 516226584Sdim // functionality of a SIMD prefix 517226584Sdim // 518226584Sdim // 0b00: None 519226584Sdim // 0b01: 66 520226584Sdim // 0b10: F3 521226584Sdim // 0b11: F2 522226584Sdim // 523226584Sdim unsigned char VEX_PP = 0; 524226584Sdim 525226584Sdim // Encode the operand size opcode prefix as needed. 526226584Sdim if (TSFlags & X86II::OpSize) 527226584Sdim VEX_PP = 0x01; 528226584Sdim 529226584Sdim if ((TSFlags >> X86II::VEXShift) & X86II::VEX_W) 530226584Sdim VEX_W = 1; 531226584Sdim 532234353Sdim if ((TSFlags >> X86II::VEXShift) & X86II::XOP) 533234353Sdim XOP = 1; 534234353Sdim 535226584Sdim if ((TSFlags >> X86II::VEXShift) & X86II::VEX_L) 536226584Sdim VEX_L = 1; 537226584Sdim 538226584Sdim switch (TSFlags & X86II::Op0Mask) { 539234353Sdim default: llvm_unreachable("Invalid prefix!"); 540226584Sdim case X86II::T8: // 0F 38 541226584Sdim VEX_5M = 0x2; 542226584Sdim break; 543226584Sdim case X86II::TA: // 0F 3A 544226584Sdim VEX_5M = 0x3; 545226584Sdim break; 546234353Sdim case X86II::T8XS: // F3 0F 38 547234353Sdim VEX_PP = 0x2; 548234353Sdim VEX_5M = 0x2; 549234353Sdim break; 550234353Sdim case X86II::T8XD: // F2 0F 38 551226584Sdim VEX_PP = 0x3; 552226584Sdim VEX_5M = 0x2; 553226584Sdim break; 554234353Sdim case X86II::TAXD: // F2 0F 3A 555234353Sdim VEX_PP = 0x3; 556234353Sdim VEX_5M = 0x3; 557234353Sdim break; 558226584Sdim case X86II::XS: // F3 0F 559226584Sdim VEX_PP = 0x2; 560226584Sdim break; 561226584Sdim case X86II::XD: // F2 0F 562226584Sdim VEX_PP = 0x3; 563226584Sdim break; 564234353Sdim case X86II::XOP8: 565234353Sdim VEX_5M = 0x8; 566234353Sdim break; 567234353Sdim case X86II::XOP9: 568234353Sdim VEX_5M = 0x9; 569234353Sdim break; 570226584Sdim case X86II::A6: // Bypass: Not used by VEX 571226584Sdim case X86II::A7: // Bypass: Not used by VEX 572226584Sdim case X86II::TB: // Bypass: Not used by VEX 573226584Sdim case 0: 574226584Sdim break; // No prefix! 575226584Sdim } 576226584Sdim 577234353Sdim 578226584Sdim // Classify VEX_B, VEX_4V, VEX_R, VEX_X 579239462Sdim unsigned NumOps = Desc.getNumOperands(); 580226584Sdim unsigned CurOp = 0; 581239462Sdim if (NumOps > 1 && Desc.getOperandConstraint(1, MCOI::TIED_TO) == 0) 582239462Sdim ++CurOp; 583239462Sdim else if (NumOps > 3 && Desc.getOperandConstraint(2, MCOI::TIED_TO) == 0) { 584239462Sdim assert(Desc.getOperandConstraint(NumOps - 1, MCOI::TIED_TO) == 1); 585239462Sdim // Special case for GATHER with 2 TIED_TO operands 586239462Sdim // Skip the first 2 operands: dst, mask_wb 587239462Sdim CurOp += 2; 588239462Sdim } 589239462Sdim 590226584Sdim switch (TSFlags & X86II::FormMask) { 591234353Sdim case X86II::MRMInitReg: llvm_unreachable("FIXME: Remove this!"); 592226584Sdim case X86II::MRMDestMem: { 593226584Sdim // MRMDestMem instructions forms: 594226584Sdim // MemAddr, src1(ModR/M) 595226584Sdim // MemAddr, src1(VEX_4V), src2(ModR/M) 596226584Sdim // MemAddr, src1(ModR/M), imm8 597226584Sdim // 598226584Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(X86::AddrBaseReg).getReg())) 599226584Sdim VEX_B = 0x0; 600226584Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(X86::AddrIndexReg).getReg())) 601226584Sdim VEX_X = 0x0; 602226584Sdim 603226584Sdim CurOp = X86::AddrNumOperands; 604226584Sdim if (HasVEX_4V) 605226584Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp++); 606226584Sdim 607226584Sdim const MCOperand &MO = MI.getOperand(CurOp); 608226584Sdim if (MO.isReg() && X86II::isX86_64ExtendedReg(MO.getReg())) 609226584Sdim VEX_R = 0x0; 610226584Sdim break; 611226584Sdim } 612234353Sdim case X86II::MRMSrcMem: 613226584Sdim // MRMSrcMem instructions forms: 614226584Sdim // src1(ModR/M), MemAddr 615226584Sdim // src1(ModR/M), src2(VEX_4V), MemAddr 616226584Sdim // src1(ModR/M), MemAddr, imm8 617226584Sdim // src1(ModR/M), MemAddr, src2(VEX_I8IMM) 618226584Sdim // 619234353Sdim // FMA4: 620234353Sdim // dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM) 621234353Sdim // dst(ModR/M.reg), src1(VEX_4V), src2(VEX_I8IMM), src3(ModR/M), 622239462Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp++).getReg())) 623226584Sdim VEX_R = 0x0; 624226584Sdim 625234353Sdim if (HasVEX_4V) 626239462Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 627226584Sdim 628226584Sdim if (X86II::isX86_64ExtendedReg( 629234353Sdim MI.getOperand(MemOperand+X86::AddrBaseReg).getReg())) 630226584Sdim VEX_B = 0x0; 631226584Sdim if (X86II::isX86_64ExtendedReg( 632234353Sdim MI.getOperand(MemOperand+X86::AddrIndexReg).getReg())) 633226584Sdim VEX_X = 0x0; 634234353Sdim 635234353Sdim if (HasVEX_4VOp3) 636239462Sdim // Instruction format for 4VOp3: 637239462Sdim // src1(ModR/M), MemAddr, src3(VEX_4V) 638239462Sdim // CurOp points to start of the MemoryOperand, 639239462Sdim // it skips TIED_TO operands if exist, then increments past src1. 640239462Sdim // CurOp + X86::AddrNumOperands will point to src3. 641239462Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp+X86::AddrNumOperands); 642226584Sdim break; 643226584Sdim case X86II::MRM0m: case X86II::MRM1m: 644226584Sdim case X86II::MRM2m: case X86II::MRM3m: 645226584Sdim case X86II::MRM4m: case X86II::MRM5m: 646234353Sdim case X86II::MRM6m: case X86II::MRM7m: { 647226584Sdim // MRM[0-9]m instructions forms: 648226584Sdim // MemAddr 649234353Sdim // src1(VEX_4V), MemAddr 650234353Sdim if (HasVEX_4V) 651234353Sdim VEX_4V = getVEXRegisterEncoding(MI, 0); 652234353Sdim 653234353Sdim if (X86II::isX86_64ExtendedReg( 654234353Sdim MI.getOperand(MemOperand+X86::AddrBaseReg).getReg())) 655226584Sdim VEX_B = 0x0; 656234353Sdim if (X86II::isX86_64ExtendedReg( 657234353Sdim MI.getOperand(MemOperand+X86::AddrIndexReg).getReg())) 658226584Sdim VEX_X = 0x0; 659226584Sdim break; 660234353Sdim } 661226584Sdim case X86II::MRMSrcReg: 662226584Sdim // MRMSrcReg instructions forms: 663226584Sdim // dst(ModR/M), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM) 664226584Sdim // dst(ModR/M), src1(ModR/M) 665226584Sdim // dst(ModR/M), src1(ModR/M), imm8 666226584Sdim // 667249423Sdim // FMA4: 668249423Sdim // dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM) 669249423Sdim // dst(ModR/M.reg), src1(VEX_4V), src2(VEX_I8IMM), src3(ModR/M), 670226584Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 671226584Sdim VEX_R = 0x0; 672226584Sdim CurOp++; 673226584Sdim 674226584Sdim if (HasVEX_4V) 675226584Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp++); 676249423Sdim 677249423Sdim if (HasMemOp4) // Skip second register source (encoded in I8IMM) 678249423Sdim CurOp++; 679249423Sdim 680226584Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 681226584Sdim VEX_B = 0x0; 682234353Sdim CurOp++; 683234353Sdim if (HasVEX_4VOp3) 684234353Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp); 685226584Sdim break; 686226584Sdim case X86II::MRMDestReg: 687226584Sdim // MRMDestReg instructions forms: 688226584Sdim // dst(ModR/M), src(ModR/M) 689226584Sdim // dst(ModR/M), src(ModR/M), imm8 690249423Sdim // dst(ModR/M), src1(VEX_4V), src2(ModR/M) 691249423Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 692226584Sdim VEX_B = 0x0; 693249423Sdim CurOp++; 694249423Sdim 695249423Sdim if (HasVEX_4V) 696249423Sdim VEX_4V = getVEXRegisterEncoding(MI, CurOp++); 697249423Sdim 698249423Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg())) 699226584Sdim VEX_R = 0x0; 700226584Sdim break; 701226584Sdim case X86II::MRM0r: case X86II::MRM1r: 702226584Sdim case X86II::MRM2r: case X86II::MRM3r: 703226584Sdim case X86II::MRM4r: case X86II::MRM5r: 704226584Sdim case X86II::MRM6r: case X86II::MRM7r: 705226584Sdim // MRM0r-MRM7r instructions forms: 706226584Sdim // dst(VEX_4V), src(ModR/M), imm8 707226584Sdim VEX_4V = getVEXRegisterEncoding(MI, 0); 708226584Sdim if (X86II::isX86_64ExtendedReg(MI.getOperand(1).getReg())) 709226584Sdim VEX_B = 0x0; 710226584Sdim break; 711226584Sdim default: // RawFrm 712226584Sdim break; 713226584Sdim } 714226584Sdim 715226584Sdim // Emit segment override opcode prefix as needed. 716226584Sdim EmitSegmentOverridePrefix(TSFlags, CurByte, MemOperand, MI, OS); 717226584Sdim 718226584Sdim // VEX opcode prefix can have 2 or 3 bytes 719226584Sdim // 720226584Sdim // 3 bytes: 721226584Sdim // +-----+ +--------------+ +-------------------+ 722226584Sdim // | C4h | | RXB | m-mmmm | | W | vvvv | L | pp | 723226584Sdim // +-----+ +--------------+ +-------------------+ 724226584Sdim // 2 bytes: 725226584Sdim // +-----+ +-------------------+ 726226584Sdim // | C5h | | R | vvvv | L | pp | 727226584Sdim // +-----+ +-------------------+ 728226584Sdim // 729226584Sdim unsigned char LastByte = VEX_PP | (VEX_L << 2) | (VEX_4V << 3); 730226584Sdim 731234353Sdim if (VEX_B && VEX_X && !VEX_W && !XOP && (VEX_5M == 1)) { // 2 byte VEX prefix 732226584Sdim EmitByte(0xC5, CurByte, OS); 733226584Sdim EmitByte(LastByte | (VEX_R << 7), CurByte, OS); 734226584Sdim return; 735226584Sdim } 736226584Sdim 737226584Sdim // 3 byte VEX prefix 738234353Sdim EmitByte(XOP ? 0x8F : 0xC4, CurByte, OS); 739226584Sdim EmitByte(VEX_R << 7 | VEX_X << 6 | VEX_B << 5 | VEX_5M, CurByte, OS); 740226584Sdim EmitByte(LastByte | (VEX_W << 7), CurByte, OS); 741226584Sdim} 742226584Sdim 743226584Sdim/// DetermineREXPrefix - Determine if the MCInst has to be encoded with a X86-64 744226584Sdim/// REX prefix which specifies 1) 64-bit instructions, 2) non-default operand 745226584Sdim/// size, and 3) use of X86-64 extended registers. 746226584Sdimstatic unsigned DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags, 747226584Sdim const MCInstrDesc &Desc) { 748226584Sdim unsigned REX = 0; 749226584Sdim if (TSFlags & X86II::REX_W) 750226584Sdim REX |= 1 << 3; // set REX.W 751226584Sdim 752226584Sdim if (MI.getNumOperands() == 0) return REX; 753226584Sdim 754226584Sdim unsigned NumOps = MI.getNumOperands(); 755226584Sdim // FIXME: MCInst should explicitize the two-addrness. 756226584Sdim bool isTwoAddr = NumOps > 1 && 757226584Sdim Desc.getOperandConstraint(1, MCOI::TIED_TO) != -1; 758226584Sdim 759226584Sdim // If it accesses SPL, BPL, SIL, or DIL, then it requires a 0x40 REX prefix. 760226584Sdim unsigned i = isTwoAddr ? 1 : 0; 761226584Sdim for (; i != NumOps; ++i) { 762226584Sdim const MCOperand &MO = MI.getOperand(i); 763226584Sdim if (!MO.isReg()) continue; 764226584Sdim unsigned Reg = MO.getReg(); 765226584Sdim if (!X86II::isX86_64NonExtLowByteReg(Reg)) continue; 766226584Sdim // FIXME: The caller of DetermineREXPrefix slaps this prefix onto anything 767226584Sdim // that returns non-zero. 768226584Sdim REX |= 0x40; // REX fixed encoding prefix 769226584Sdim break; 770226584Sdim } 771226584Sdim 772226584Sdim switch (TSFlags & X86II::FormMask) { 773234353Sdim case X86II::MRMInitReg: llvm_unreachable("FIXME: Remove this!"); 774226584Sdim case X86II::MRMSrcReg: 775226584Sdim if (MI.getOperand(0).isReg() && 776226584Sdim X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) 777226584Sdim REX |= 1 << 2; // set REX.R 778226584Sdim i = isTwoAddr ? 2 : 1; 779226584Sdim for (; i != NumOps; ++i) { 780226584Sdim const MCOperand &MO = MI.getOperand(i); 781226584Sdim if (MO.isReg() && X86II::isX86_64ExtendedReg(MO.getReg())) 782226584Sdim REX |= 1 << 0; // set REX.B 783226584Sdim } 784226584Sdim break; 785226584Sdim case X86II::MRMSrcMem: { 786226584Sdim if (MI.getOperand(0).isReg() && 787226584Sdim X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) 788226584Sdim REX |= 1 << 2; // set REX.R 789226584Sdim unsigned Bit = 0; 790226584Sdim i = isTwoAddr ? 2 : 1; 791226584Sdim for (; i != NumOps; ++i) { 792226584Sdim const MCOperand &MO = MI.getOperand(i); 793226584Sdim if (MO.isReg()) { 794226584Sdim if (X86II::isX86_64ExtendedReg(MO.getReg())) 795226584Sdim REX |= 1 << Bit; // set REX.B (Bit=0) and REX.X (Bit=1) 796226584Sdim Bit++; 797226584Sdim } 798226584Sdim } 799226584Sdim break; 800226584Sdim } 801226584Sdim case X86II::MRM0m: case X86II::MRM1m: 802226584Sdim case X86II::MRM2m: case X86II::MRM3m: 803226584Sdim case X86II::MRM4m: case X86II::MRM5m: 804226584Sdim case X86II::MRM6m: case X86II::MRM7m: 805226584Sdim case X86II::MRMDestMem: { 806226584Sdim unsigned e = (isTwoAddr ? X86::AddrNumOperands+1 : X86::AddrNumOperands); 807226584Sdim i = isTwoAddr ? 1 : 0; 808226584Sdim if (NumOps > e && MI.getOperand(e).isReg() && 809226584Sdim X86II::isX86_64ExtendedReg(MI.getOperand(e).getReg())) 810226584Sdim REX |= 1 << 2; // set REX.R 811226584Sdim unsigned Bit = 0; 812226584Sdim for (; i != e; ++i) { 813226584Sdim const MCOperand &MO = MI.getOperand(i); 814226584Sdim if (MO.isReg()) { 815226584Sdim if (X86II::isX86_64ExtendedReg(MO.getReg())) 816226584Sdim REX |= 1 << Bit; // REX.B (Bit=0) and REX.X (Bit=1) 817226584Sdim Bit++; 818226584Sdim } 819226584Sdim } 820226584Sdim break; 821226584Sdim } 822226584Sdim default: 823226584Sdim if (MI.getOperand(0).isReg() && 824226584Sdim X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) 825226584Sdim REX |= 1 << 0; // set REX.B 826226584Sdim i = isTwoAddr ? 2 : 1; 827226584Sdim for (unsigned e = NumOps; i != e; ++i) { 828226584Sdim const MCOperand &MO = MI.getOperand(i); 829226584Sdim if (MO.isReg() && X86II::isX86_64ExtendedReg(MO.getReg())) 830226584Sdim REX |= 1 << 2; // set REX.R 831226584Sdim } 832226584Sdim break; 833226584Sdim } 834226584Sdim return REX; 835226584Sdim} 836226584Sdim 837226584Sdim/// EmitSegmentOverridePrefix - Emit segment override opcode prefix as needed 838226584Sdimvoid X86MCCodeEmitter::EmitSegmentOverridePrefix(uint64_t TSFlags, 839226584Sdim unsigned &CurByte, int MemOperand, 840226584Sdim const MCInst &MI, 841226584Sdim raw_ostream &OS) const { 842226584Sdim switch (TSFlags & X86II::SegOvrMask) { 843234353Sdim default: llvm_unreachable("Invalid segment!"); 844226584Sdim case 0: 845226584Sdim // No segment override, check for explicit one on memory operand. 846226584Sdim if (MemOperand != -1) { // If the instruction has a memory operand. 847226584Sdim switch (MI.getOperand(MemOperand+X86::AddrSegmentReg).getReg()) { 848234353Sdim default: llvm_unreachable("Unknown segment register!"); 849226584Sdim case 0: break; 850226584Sdim case X86::CS: EmitByte(0x2E, CurByte, OS); break; 851226584Sdim case X86::SS: EmitByte(0x36, CurByte, OS); break; 852226584Sdim case X86::DS: EmitByte(0x3E, CurByte, OS); break; 853226584Sdim case X86::ES: EmitByte(0x26, CurByte, OS); break; 854226584Sdim case X86::FS: EmitByte(0x64, CurByte, OS); break; 855226584Sdim case X86::GS: EmitByte(0x65, CurByte, OS); break; 856226584Sdim } 857226584Sdim } 858226584Sdim break; 859226584Sdim case X86II::FS: 860226584Sdim EmitByte(0x64, CurByte, OS); 861226584Sdim break; 862226584Sdim case X86II::GS: 863226584Sdim EmitByte(0x65, CurByte, OS); 864226584Sdim break; 865226584Sdim } 866226584Sdim} 867226584Sdim 868226584Sdim/// EmitOpcodePrefix - Emit all instruction prefixes prior to the opcode. 869226584Sdim/// 870226584Sdim/// MemOperand is the operand # of the start of a memory operand if present. If 871226584Sdim/// Not present, it is -1. 872226584Sdimvoid X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, 873226584Sdim int MemOperand, const MCInst &MI, 874226584Sdim const MCInstrDesc &Desc, 875226584Sdim raw_ostream &OS) const { 876226584Sdim 877226584Sdim // Emit the lock opcode prefix as needed. 878226584Sdim if (TSFlags & X86II::LOCK) 879226584Sdim EmitByte(0xF0, CurByte, OS); 880226584Sdim 881226584Sdim // Emit segment override opcode prefix as needed. 882226584Sdim EmitSegmentOverridePrefix(TSFlags, CurByte, MemOperand, MI, OS); 883226584Sdim 884226584Sdim // Emit the repeat opcode prefix as needed. 885226584Sdim if ((TSFlags & X86II::Op0Mask) == X86II::REP) 886226584Sdim EmitByte(0xF3, CurByte, OS); 887226584Sdim 888226584Sdim // Emit the address size opcode prefix as needed. 889234353Sdim bool need_address_override; 890234353Sdim if (TSFlags & X86II::AdSize) { 891234353Sdim need_address_override = true; 892234353Sdim } else if (MemOperand == -1) { 893234353Sdim need_address_override = false; 894234353Sdim } else if (is64BitMode()) { 895234353Sdim assert(!Is16BitMemOperand(MI, MemOperand)); 896234353Sdim need_address_override = Is32BitMemOperand(MI, MemOperand); 897234353Sdim } else if (is32BitMode()) { 898234353Sdim assert(!Is64BitMemOperand(MI, MemOperand)); 899234353Sdim need_address_override = Is16BitMemOperand(MI, MemOperand); 900234353Sdim } else { 901234353Sdim need_address_override = false; 902234353Sdim } 903234353Sdim 904234353Sdim if (need_address_override) 905226584Sdim EmitByte(0x67, CurByte, OS); 906226584Sdim 907226584Sdim // Emit the operand size opcode prefix as needed. 908226584Sdim if (TSFlags & X86II::OpSize) 909226584Sdim EmitByte(0x66, CurByte, OS); 910226584Sdim 911226584Sdim bool Need0FPrefix = false; 912226584Sdim switch (TSFlags & X86II::Op0Mask) { 913234353Sdim default: llvm_unreachable("Invalid prefix!"); 914226584Sdim case 0: break; // No prefix! 915226584Sdim case X86II::REP: break; // already handled. 916226584Sdim case X86II::TB: // Two-byte opcode prefix 917226584Sdim case X86II::T8: // 0F 38 918226584Sdim case X86II::TA: // 0F 3A 919226584Sdim case X86II::A6: // 0F A6 920226584Sdim case X86II::A7: // 0F A7 921226584Sdim Need0FPrefix = true; 922226584Sdim break; 923234353Sdim case X86II::T8XS: // F3 0F 38 924234353Sdim EmitByte(0xF3, CurByte, OS); 925234353Sdim Need0FPrefix = true; 926234353Sdim break; 927234353Sdim case X86II::T8XD: // F2 0F 38 928226584Sdim EmitByte(0xF2, CurByte, OS); 929226584Sdim Need0FPrefix = true; 930226584Sdim break; 931234353Sdim case X86II::TAXD: // F2 0F 3A 932234353Sdim EmitByte(0xF2, CurByte, OS); 933234353Sdim Need0FPrefix = true; 934234353Sdim break; 935226584Sdim case X86II::XS: // F3 0F 936226584Sdim EmitByte(0xF3, CurByte, OS); 937226584Sdim Need0FPrefix = true; 938226584Sdim break; 939226584Sdim case X86II::XD: // F2 0F 940226584Sdim EmitByte(0xF2, CurByte, OS); 941226584Sdim Need0FPrefix = true; 942226584Sdim break; 943226584Sdim case X86II::D8: EmitByte(0xD8, CurByte, OS); break; 944226584Sdim case X86II::D9: EmitByte(0xD9, CurByte, OS); break; 945226584Sdim case X86II::DA: EmitByte(0xDA, CurByte, OS); break; 946226584Sdim case X86II::DB: EmitByte(0xDB, CurByte, OS); break; 947226584Sdim case X86II::DC: EmitByte(0xDC, CurByte, OS); break; 948226584Sdim case X86II::DD: EmitByte(0xDD, CurByte, OS); break; 949226584Sdim case X86II::DE: EmitByte(0xDE, CurByte, OS); break; 950226584Sdim case X86II::DF: EmitByte(0xDF, CurByte, OS); break; 951226584Sdim } 952226584Sdim 953226584Sdim // Handle REX prefix. 954226584Sdim // FIXME: Can this come before F2 etc to simplify emission? 955226584Sdim if (is64BitMode()) { 956226584Sdim if (unsigned REX = DetermineREXPrefix(MI, TSFlags, Desc)) 957226584Sdim EmitByte(0x40 | REX, CurByte, OS); 958226584Sdim } 959226584Sdim 960226584Sdim // 0x0F escape code must be emitted just before the opcode. 961226584Sdim if (Need0FPrefix) 962226584Sdim EmitByte(0x0F, CurByte, OS); 963226584Sdim 964226584Sdim // FIXME: Pull this up into previous switch if REX can be moved earlier. 965226584Sdim switch (TSFlags & X86II::Op0Mask) { 966234353Sdim case X86II::T8XS: // F3 0F 38 967234353Sdim case X86II::T8XD: // F2 0F 38 968226584Sdim case X86II::T8: // 0F 38 969226584Sdim EmitByte(0x38, CurByte, OS); 970226584Sdim break; 971234353Sdim case X86II::TAXD: // F2 0F 3A 972226584Sdim case X86II::TA: // 0F 3A 973226584Sdim EmitByte(0x3A, CurByte, OS); 974226584Sdim break; 975226584Sdim case X86II::A6: // 0F A6 976226584Sdim EmitByte(0xA6, CurByte, OS); 977226584Sdim break; 978226584Sdim case X86II::A7: // 0F A7 979226584Sdim EmitByte(0xA7, CurByte, OS); 980226584Sdim break; 981226584Sdim } 982226584Sdim} 983226584Sdim 984226584Sdimvoid X86MCCodeEmitter:: 985226584SdimEncodeInstruction(const MCInst &MI, raw_ostream &OS, 986226584Sdim SmallVectorImpl<MCFixup> &Fixups) const { 987226584Sdim unsigned Opcode = MI.getOpcode(); 988226584Sdim const MCInstrDesc &Desc = MCII.get(Opcode); 989226584Sdim uint64_t TSFlags = Desc.TSFlags; 990226584Sdim 991226584Sdim // Pseudo instructions don't get encoded. 992226584Sdim if ((TSFlags & X86II::FormMask) == X86II::Pseudo) 993226584Sdim return; 994226584Sdim 995226584Sdim unsigned NumOps = Desc.getNumOperands(); 996251662Sdim unsigned CurOp = X86II::getOperandBias(Desc); 997226584Sdim 998226584Sdim // Keep track of the current byte being emitted. 999226584Sdim unsigned CurByte = 0; 1000226584Sdim 1001226584Sdim // Is this instruction encoded using the AVX VEX prefix? 1002234353Sdim bool HasVEXPrefix = (TSFlags >> X86II::VEXShift) & X86II::VEX; 1003226584Sdim 1004226584Sdim // It uses the VEX.VVVV field? 1005234353Sdim bool HasVEX_4V = (TSFlags >> X86II::VEXShift) & X86II::VEX_4V; 1006234353Sdim bool HasVEX_4VOp3 = (TSFlags >> X86II::VEXShift) & X86II::VEX_4VOp3; 1007234353Sdim bool HasMemOp4 = (TSFlags >> X86II::VEXShift) & X86II::MemOp4; 1008234353Sdim const unsigned MemOp4_I8IMMOperand = 2; 1009226584Sdim 1010226584Sdim // Determine where the memory operand starts, if present. 1011234353Sdim int MemoryOperand = X86II::getMemoryOperandNo(TSFlags, Opcode); 1012226584Sdim if (MemoryOperand != -1) MemoryOperand += CurOp; 1013226584Sdim 1014226584Sdim if (!HasVEXPrefix) 1015226584Sdim EmitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS); 1016226584Sdim else 1017226584Sdim EmitVEXOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS); 1018226584Sdim 1019226584Sdim unsigned char BaseOpcode = X86II::getBaseOpcodeFor(TSFlags); 1020226584Sdim 1021226584Sdim if ((TSFlags >> X86II::VEXShift) & X86II::Has3DNow0F0FOpcode) 1022226584Sdim BaseOpcode = 0x0F; // Weird 3DNow! encoding. 1023226584Sdim 1024226584Sdim unsigned SrcRegNum = 0; 1025226584Sdim switch (TSFlags & X86II::FormMask) { 1026226584Sdim case X86II::MRMInitReg: 1027234353Sdim llvm_unreachable("FIXME: Remove this form when the JIT moves to MCCodeEmitter!"); 1028226584Sdim default: errs() << "FORM: " << (TSFlags & X86II::FormMask) << "\n"; 1029234353Sdim llvm_unreachable("Unknown FormMask value in X86MCCodeEmitter!"); 1030226584Sdim case X86II::Pseudo: 1031234353Sdim llvm_unreachable("Pseudo instruction shouldn't be emitted"); 1032226584Sdim case X86II::RawFrm: 1033226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1034226584Sdim break; 1035226584Sdim case X86II::RawFrmImm8: 1036226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1037234353Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1038226584Sdim X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), 1039226584Sdim CurByte, OS, Fixups); 1040234353Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1, FK_Data_1, CurByte, 1041234353Sdim OS, Fixups); 1042226584Sdim break; 1043226584Sdim case X86II::RawFrmImm16: 1044226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1045234353Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1046226584Sdim X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), 1047226584Sdim CurByte, OS, Fixups); 1048234353Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 2, FK_Data_2, CurByte, 1049234353Sdim OS, Fixups); 1050226584Sdim break; 1051226584Sdim 1052226584Sdim case X86II::AddRegFrm: 1053226584Sdim EmitByte(BaseOpcode + GetX86RegNum(MI.getOperand(CurOp++)), CurByte, OS); 1054226584Sdim break; 1055226584Sdim 1056226584Sdim case X86II::MRMDestReg: 1057226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1058249423Sdim SrcRegNum = CurOp + 1; 1059249423Sdim 1060249423Sdim if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV) 1061249423Sdim ++SrcRegNum; 1062249423Sdim 1063226584Sdim EmitRegModRMByte(MI.getOperand(CurOp), 1064249423Sdim GetX86RegNum(MI.getOperand(SrcRegNum)), CurByte, OS); 1065249423Sdim CurOp = SrcRegNum + 1; 1066226584Sdim break; 1067226584Sdim 1068226584Sdim case X86II::MRMDestMem: 1069226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1070226584Sdim SrcRegNum = CurOp + X86::AddrNumOperands; 1071226584Sdim 1072226584Sdim if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV) 1073239462Sdim ++SrcRegNum; 1074226584Sdim 1075226584Sdim EmitMemModRMByte(MI, CurOp, 1076226584Sdim GetX86RegNum(MI.getOperand(SrcRegNum)), 1077226584Sdim TSFlags, CurByte, OS, Fixups); 1078226584Sdim CurOp = SrcRegNum + 1; 1079226584Sdim break; 1080226584Sdim 1081226584Sdim case X86II::MRMSrcReg: 1082226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1083226584Sdim SrcRegNum = CurOp + 1; 1084226584Sdim 1085226584Sdim if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV) 1086239462Sdim ++SrcRegNum; 1087226584Sdim 1088239462Sdim if (HasMemOp4) // Skip 2nd src (which is encoded in I8IMM) 1089239462Sdim ++SrcRegNum; 1090234353Sdim 1091226584Sdim EmitRegModRMByte(MI.getOperand(SrcRegNum), 1092226584Sdim GetX86RegNum(MI.getOperand(CurOp)), CurByte, OS); 1093234353Sdim 1094239462Sdim // 2 operands skipped with HasMemOp4, compensate accordingly 1095234353Sdim CurOp = HasMemOp4 ? SrcRegNum : SrcRegNum + 1; 1096234353Sdim if (HasVEX_4VOp3) 1097234353Sdim ++CurOp; 1098226584Sdim break; 1099226584Sdim 1100226584Sdim case X86II::MRMSrcMem: { 1101226584Sdim int AddrOperands = X86::AddrNumOperands; 1102226584Sdim unsigned FirstMemOp = CurOp+1; 1103226584Sdim if (HasVEX_4V) { 1104226584Sdim ++AddrOperands; 1105226584Sdim ++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV). 1106226584Sdim } 1107239462Sdim if (HasMemOp4) // Skip second register source (encoded in I8IMM) 1108234353Sdim ++FirstMemOp; 1109226584Sdim 1110226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1111226584Sdim 1112226584Sdim EmitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)), 1113226584Sdim TSFlags, CurByte, OS, Fixups); 1114226584Sdim CurOp += AddrOperands + 1; 1115234353Sdim if (HasVEX_4VOp3) 1116234353Sdim ++CurOp; 1117226584Sdim break; 1118226584Sdim } 1119226584Sdim 1120226584Sdim case X86II::MRM0r: case X86II::MRM1r: 1121226584Sdim case X86II::MRM2r: case X86II::MRM3r: 1122226584Sdim case X86II::MRM4r: case X86II::MRM5r: 1123226584Sdim case X86II::MRM6r: case X86II::MRM7r: 1124226584Sdim if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV). 1125239462Sdim ++CurOp; 1126226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1127226584Sdim EmitRegModRMByte(MI.getOperand(CurOp++), 1128226584Sdim (TSFlags & X86II::FormMask)-X86II::MRM0r, 1129226584Sdim CurByte, OS); 1130226584Sdim break; 1131226584Sdim case X86II::MRM0m: case X86II::MRM1m: 1132226584Sdim case X86II::MRM2m: case X86II::MRM3m: 1133226584Sdim case X86II::MRM4m: case X86II::MRM5m: 1134226584Sdim case X86II::MRM6m: case X86II::MRM7m: 1135234353Sdim if (HasVEX_4V) // Skip the register dst (which is encoded in VEX_VVVV). 1136239462Sdim ++CurOp; 1137226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1138226584Sdim EmitMemModRMByte(MI, CurOp, (TSFlags & X86II::FormMask)-X86II::MRM0m, 1139226584Sdim TSFlags, CurByte, OS, Fixups); 1140226584Sdim CurOp += X86::AddrNumOperands; 1141226584Sdim break; 1142249423Sdim case X86II::MRM_C1: case X86II::MRM_C2: case X86II::MRM_C3: 1143249423Sdim case X86II::MRM_C4: case X86II::MRM_C8: case X86II::MRM_C9: 1144251662Sdim case X86II::MRM_CA: case X86II::MRM_CB: case X86II::MRM_D0: 1145251662Sdim case X86II::MRM_D1: case X86II::MRM_D4: case X86II::MRM_D5: 1146251662Sdim case X86II::MRM_D6: case X86II::MRM_D8: case X86II::MRM_D9: 1147251662Sdim case X86II::MRM_DA: case X86II::MRM_DB: case X86II::MRM_DC: 1148251662Sdim case X86II::MRM_DD: case X86II::MRM_DE: case X86II::MRM_DF: 1149251662Sdim case X86II::MRM_E8: case X86II::MRM_F0: case X86II::MRM_F8: 1150251662Sdim case X86II::MRM_F9: 1151226584Sdim EmitByte(BaseOpcode, CurByte, OS); 1152234353Sdim 1153234353Sdim unsigned char MRM; 1154234353Sdim switch (TSFlags & X86II::FormMask) { 1155234353Sdim default: llvm_unreachable("Invalid Form"); 1156234353Sdim case X86II::MRM_C1: MRM = 0xC1; break; 1157234353Sdim case X86II::MRM_C2: MRM = 0xC2; break; 1158234353Sdim case X86II::MRM_C3: MRM = 0xC3; break; 1159234353Sdim case X86II::MRM_C4: MRM = 0xC4; break; 1160234353Sdim case X86II::MRM_C8: MRM = 0xC8; break; 1161234353Sdim case X86II::MRM_C9: MRM = 0xC9; break; 1162251662Sdim case X86II::MRM_CA: MRM = 0xCA; break; 1163251662Sdim case X86II::MRM_CB: MRM = 0xCB; break; 1164234353Sdim case X86II::MRM_D0: MRM = 0xD0; break; 1165234353Sdim case X86II::MRM_D1: MRM = 0xD1; break; 1166234353Sdim case X86II::MRM_D4: MRM = 0xD4; break; 1167243830Sdim case X86II::MRM_D5: MRM = 0xD5; break; 1168249423Sdim case X86II::MRM_D6: MRM = 0xD6; break; 1169234353Sdim case X86II::MRM_D8: MRM = 0xD8; break; 1170234353Sdim case X86II::MRM_D9: MRM = 0xD9; break; 1171234353Sdim case X86II::MRM_DA: MRM = 0xDA; break; 1172234353Sdim case X86II::MRM_DB: MRM = 0xDB; break; 1173234353Sdim case X86II::MRM_DC: MRM = 0xDC; break; 1174234353Sdim case X86II::MRM_DD: MRM = 0xDD; break; 1175234353Sdim case X86II::MRM_DE: MRM = 0xDE; break; 1176234353Sdim case X86II::MRM_DF: MRM = 0xDF; break; 1177234353Sdim case X86II::MRM_E8: MRM = 0xE8; break; 1178234353Sdim case X86II::MRM_F0: MRM = 0xF0; break; 1179234353Sdim case X86II::MRM_F8: MRM = 0xF8; break; 1180234353Sdim case X86II::MRM_F9: MRM = 0xF9; break; 1181234353Sdim } 1182234353Sdim EmitByte(MRM, CurByte, OS); 1183226584Sdim break; 1184226584Sdim } 1185226584Sdim 1186226584Sdim // If there is a remaining operand, it must be a trailing immediate. Emit it 1187239462Sdim // according to the right size for the instruction. Some instructions 1188239462Sdim // (SSE4a extrq and insertq) have two trailing immediates. 1189239462Sdim while (CurOp != NumOps && NumOps - CurOp <= 2) { 1190226584Sdim // The last source register of a 4 operand instruction in AVX is encoded 1191234353Sdim // in bits[7:4] of a immediate byte. 1192226584Sdim if ((TSFlags >> X86II::VEXShift) & X86II::VEX_I8IMM) { 1193234353Sdim const MCOperand &MO = MI.getOperand(HasMemOp4 ? MemOp4_I8IMMOperand 1194239462Sdim : CurOp); 1195239462Sdim ++CurOp; 1196239462Sdim unsigned RegNum = GetX86RegNum(MO) << 4; 1197239462Sdim if (X86II::isX86_64ExtendedReg(MO.getReg())) 1198239462Sdim RegNum |= 1 << 7; 1199234353Sdim // If there is an additional 5th operand it must be an immediate, which 1200234353Sdim // is encoded in bits[3:0] 1201239462Sdim if (CurOp != NumOps) { 1202234353Sdim const MCOperand &MIMM = MI.getOperand(CurOp++); 1203239462Sdim if (MIMM.isImm()) { 1204234353Sdim unsigned Val = MIMM.getImm(); 1205234353Sdim assert(Val < 16 && "Immediate operand value out of range"); 1206234353Sdim RegNum |= Val; 1207234353Sdim } 1208234353Sdim } 1209234353Sdim EmitImmediate(MCOperand::CreateImm(RegNum), MI.getLoc(), 1, FK_Data_1, 1210234353Sdim CurByte, OS, Fixups); 1211226584Sdim } else { 1212226584Sdim unsigned FixupKind; 1213226584Sdim // FIXME: Is there a better way to know that we need a signed relocation? 1214226584Sdim if (MI.getOpcode() == X86::ADD64ri32 || 1215226584Sdim MI.getOpcode() == X86::MOV64ri32 || 1216226584Sdim MI.getOpcode() == X86::MOV64mi32 || 1217226584Sdim MI.getOpcode() == X86::PUSH64i32) 1218226584Sdim FixupKind = X86::reloc_signed_4byte; 1219226584Sdim else 1220226584Sdim FixupKind = getImmFixupKind(TSFlags); 1221234353Sdim EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1222226584Sdim X86II::getSizeOfImm(TSFlags), MCFixupKind(FixupKind), 1223226584Sdim CurByte, OS, Fixups); 1224226584Sdim } 1225226584Sdim } 1226226584Sdim 1227226584Sdim if ((TSFlags >> X86II::VEXShift) & X86II::Has3DNow0F0FOpcode) 1228226584Sdim EmitByte(X86II::getBaseOpcodeFor(TSFlags), CurByte, OS); 1229226584Sdim 1230226584Sdim#ifndef NDEBUG 1231226584Sdim // FIXME: Verify. 1232226584Sdim if (/*!Desc.isVariadic() &&*/ CurOp != NumOps) { 1233226584Sdim errs() << "Cannot encode all operands of: "; 1234226584Sdim MI.dump(); 1235226584Sdim errs() << '\n'; 1236226584Sdim abort(); 1237226584Sdim } 1238226584Sdim#endif 1239226584Sdim} 1240