Commit 90ccc3fa by Jan Voung

Rename AssemblerX86 to AssemblerX8632 so it works with SZTargets.def.

This is to conditionally (ifdef) include only the enabled target assemblers. Also rename the assembler's "x86" namespace to "X8632" for similar reasons. The namespace was created to hide generic sounding classes like "Address" which are used all over the assembler. Plop the somewhat empty AssemblerARM32 in an ARM32 namespace for consistency. BUG=none R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1114223002
parent 4175b2a6
...@@ -76,8 +76,8 @@ public: ...@@ -76,8 +76,8 @@ public:
Variable *getIndex() const { return Index; } Variable *getIndex() const { return Index; }
uint16_t getShift() const { return Shift; } uint16_t getShift() const { return Shift; }
SegmentRegisters getSegmentRegister() const { return SegmentReg; } SegmentRegisters getSegmentRegister() const { return SegmentReg; }
void emitSegmentOverride(x86::AssemblerX86 *Asm) const; void emitSegmentOverride(X8632::AssemblerX8632 *Asm) const;
x86::Address toAsmAddress(Assembler *Asm) const; X8632::Address toAsmAddress(Assembler *Asm) const;
void emit(const Cfg *Func) const override; void emit(const Cfg *Func) const override;
using OperandX8632::dump; using OperandX8632::dump;
void dump(const Cfg *Func, Ostream &Str) const override; void dump(const Cfg *Func, Ostream &Str) const override;
...@@ -115,7 +115,7 @@ public: ...@@ -115,7 +115,7 @@ public:
} }
int32_t getOffset() const { return Part == High ? 4 : 0; } int32_t getOffset() const { return Part == High ? 4 : 0; }
x86::Address toAsmAddress(const Cfg *Func) const; X8632::Address toAsmAddress(const Cfg *Func) const;
void emit(const Cfg *Func) const override; void emit(const Cfg *Func) const override;
using OperandX8632::dump; using OperandX8632::dump;
void dump(const Cfg *Func, Ostream &Str) const override; void dump(const Cfg *Func, Ostream &Str) const override;
...@@ -501,7 +501,7 @@ private: ...@@ -501,7 +501,7 @@ private:
// Emit a one-operand (GPR) instruction. // Emit a one-operand (GPR) instruction.
void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var, void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var,
const x86::AssemblerX86::GPREmitterOneOp &Emitter); const X8632::AssemblerX8632::GPREmitterOneOp &Emitter);
// Instructions of the form x := op(x). // Instructions of the form x := op(x).
template <InstX8632::InstKindX8632 K> template <InstX8632::InstKindX8632 K>
...@@ -546,7 +546,7 @@ private: ...@@ -546,7 +546,7 @@ private:
} }
~InstX8632InplaceopGPR() override {} ~InstX8632InplaceopGPR() override {}
static const char *Opcode; static const char *Opcode;
static const x86::AssemblerX86::GPREmitterOneOp Emitter; static const X8632::AssemblerX8632::GPREmitterOneOp Emitter;
}; };
// Emit a two-operand (GPR) instruction, where the dest operand is a // Emit a two-operand (GPR) instruction, where the dest operand is a
...@@ -554,7 +554,7 @@ private: ...@@ -554,7 +554,7 @@ private:
template <bool VarCanBeByte = true, bool SrcCanBeByte = true> template <bool VarCanBeByte = true, bool SrcCanBeByte = true>
void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst, void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst,
const Operand *Src, const Operand *Src,
const x86::AssemblerX86::GPREmitterRegOp &Emitter); const X8632::AssemblerX8632::GPREmitterRegOp &Emitter);
// Instructions of the form x := op(y). // Instructions of the form x := op(y).
template <InstX8632::InstKindX8632 K> template <InstX8632::InstKindX8632 K>
...@@ -610,12 +610,12 @@ private: ...@@ -610,12 +610,12 @@ private:
} }
~InstX8632UnaryopGPR() override {} ~InstX8632UnaryopGPR() override {}
static const char *Opcode; static const char *Opcode;
static const x86::AssemblerX86::GPREmitterRegOp Emitter; static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
}; };
void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
const Operand *Src, const Operand *Src,
const x86::AssemblerX86::XmmEmitterRegOp &Emitter); const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter);
template <InstX8632::InstKindX8632 K> template <InstX8632::InstKindX8632 K>
class InstX8632UnaryopXmm : public InstX8632 { class InstX8632UnaryopXmm : public InstX8632 {
...@@ -660,7 +660,7 @@ private: ...@@ -660,7 +660,7 @@ private:
} }
~InstX8632UnaryopXmm() override {} ~InstX8632UnaryopXmm() override {}
static const char *Opcode; static const char *Opcode;
static const x86::AssemblerX86::XmmEmitterRegOp Emitter; static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
}; };
// See the definition of emitTwoAddress() for a description of // See the definition of emitTwoAddress() for a description of
...@@ -670,7 +670,7 @@ void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, ...@@ -670,7 +670,7 @@ void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
const Operand *Src, const Operand *Src,
const x86::AssemblerX86::GPREmitterShiftOp &Emitter); const X8632::AssemblerX8632::GPREmitterShiftOp &Emitter);
template <InstX8632::InstKindX8632 K> template <InstX8632::InstKindX8632 K>
class InstX8632BinopGPRShift : public InstX8632 { class InstX8632BinopGPRShift : public InstX8632 {
...@@ -714,7 +714,7 @@ private: ...@@ -714,7 +714,7 @@ private:
} }
~InstX8632BinopGPRShift() override {} ~InstX8632BinopGPRShift() override {}
static const char *Opcode; static const char *Opcode;
static const x86::AssemblerX86::GPREmitterShiftOp Emitter; static const X8632::AssemblerX8632::GPREmitterShiftOp Emitter;
}; };
template <InstX8632::InstKindX8632 K> template <InstX8632::InstKindX8632 K>
...@@ -758,7 +758,7 @@ private: ...@@ -758,7 +758,7 @@ private:
} }
~InstX8632BinopGPR() override {} ~InstX8632BinopGPR() override {}
static const char *Opcode; static const char *Opcode;
static const x86::AssemblerX86::GPREmitterRegOp Emitter; static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
}; };
template <InstX8632::InstKindX8632 K, bool NeedsElementType> template <InstX8632::InstKindX8632 K, bool NeedsElementType>
...@@ -806,12 +806,12 @@ private: ...@@ -806,12 +806,12 @@ private:
} }
~InstX8632BinopXmm() override {} ~InstX8632BinopXmm() override {}
static const char *Opcode; static const char *Opcode;
static const x86::AssemblerX86::XmmEmitterRegOp Emitter; static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
}; };
void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var,
const Operand *Src, const Operand *Src,
const x86::AssemblerX86::XmmEmitterShiftOp &Emitter); const X8632::AssemblerX8632::XmmEmitterShiftOp &Emitter);
template <InstX8632::InstKindX8632 K, bool AllowAllTypes = false> template <InstX8632::InstKindX8632 K, bool AllowAllTypes = false>
class InstX8632BinopXmmShift : public InstX8632 { class InstX8632BinopXmmShift : public InstX8632 {
...@@ -859,7 +859,7 @@ private: ...@@ -859,7 +859,7 @@ private:
} }
~InstX8632BinopXmmShift() override {} ~InstX8632BinopXmmShift() override {}
static const char *Opcode; static const char *Opcode;
static const x86::AssemblerX86::XmmEmitterShiftOp Emitter; static const X8632::AssemblerX8632::XmmEmitterShiftOp Emitter;
}; };
template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 { template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 {
......
...@@ -80,15 +80,10 @@ TargetLowering::TargetLowering(Cfg *Func) ...@@ -80,15 +80,10 @@ TargetLowering::TargetLowering(Cfg *Func)
std::unique_ptr<Assembler> TargetLowering::createAssembler(TargetArch Target, std::unique_ptr<Assembler> TargetLowering::createAssembler(TargetArch Target,
Cfg *Func) { Cfg *Func) {
// These statements can be #ifdef'd to specialize the assembler #define SUBZERO_TARGET(X) \
// to a subset of the available targets. TODO: use CRTP. if (Target == Target_##X) \
// TODO(jvoung): use SZTargets.def (rename AssemblerX86 -> AssemblerX8632), return std::unique_ptr<Assembler>(new X::Assembler##X());
// and make the namespaces consistent. #include "llvm/Config/SZTargets.def"
if (Target == Target_X8632)
return std::unique_ptr<Assembler>(new x86::AssemblerX86());
if (Target == Target_ARM32)
return std::unique_ptr<Assembler>(new AssemblerARM32());
Func->setError("Unsupported target assembler"); Func->setError("Unsupported target assembler");
return nullptr; return nullptr;
......
...@@ -518,7 +518,7 @@ void TargetX8632::emitVariable(const Variable *Var) const { ...@@ -518,7 +518,7 @@ void TargetX8632::emitVariable(const Variable *Var) const {
Str << "(%" << getRegName(getFrameOrStackReg(), Ty) << ")"; Str << "(%" << getRegName(getFrameOrStackReg(), Ty) << ")";
} }
x86::Address TargetX8632::stackVarToAsmOperand(const Variable *Var) const { X8632::Address TargetX8632::stackVarToAsmOperand(const Variable *Var) const {
if (Var->hasReg()) if (Var->hasReg())
llvm_unreachable("Stack Variable has a register assigned"); llvm_unreachable("Stack Variable has a register assigned");
if (Var->getWeight().isInf()) if (Var->getWeight().isInf())
...@@ -526,7 +526,7 @@ x86::Address TargetX8632::stackVarToAsmOperand(const Variable *Var) const { ...@@ -526,7 +526,7 @@ x86::Address TargetX8632::stackVarToAsmOperand(const Variable *Var) const {
int32_t Offset = Var->getStackOffset(); int32_t Offset = Var->getStackOffset();
if (!hasFramePointer()) if (!hasFramePointer())
Offset += getStackAdjustment(); Offset += getStackAdjustment();
return x86::Address(RegX8632::getEncodedGPR(getFrameOrStackReg()), Offset); return X8632::Address(RegX8632::getEncodedGPR(getFrameOrStackReg()), Offset);
} }
void TargetX8632::lowerArguments() { void TargetX8632::lowerArguments() {
......
...@@ -67,7 +67,7 @@ public: ...@@ -67,7 +67,7 @@ public:
size_t BasicFrameOffset, size_t &InArgsSizeBytes); size_t BasicFrameOffset, size_t &InArgsSizeBytes);
Operand *loOperand(Operand *Operand); Operand *loOperand(Operand *Operand);
Operand *hiOperand(Operand *Operand); Operand *hiOperand(Operand *Operand);
x86::Address stackVarToAsmOperand(const Variable *Var) const; X8632::Address stackVarToAsmOperand(const Variable *Var) const;
enum X86InstructionSet { enum X86InstructionSet {
Begin, Begin,
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "assembler.h" #include "assembler.h"
namespace Ice { namespace Ice {
namespace ARM32 {
class AssemblerARM32 : public Assembler { class AssemblerARM32 : public Assembler {
AssemblerARM32(const AssemblerARM32 &) = delete; AssemblerARM32(const AssemblerARM32 &) = delete;
...@@ -67,6 +68,7 @@ public: ...@@ -67,6 +68,7 @@ public:
} }
}; };
} // end of namespace ARM32
} // end of namespace Ice } // end of namespace Ice
#endif // SUBZERO_SRC_ASSEMBLER_ARM32_H #endif // SUBZERO_SRC_ASSEMBLER_ARM32_H
...@@ -38,7 +38,7 @@ using RegX8632::XmmRegister; ...@@ -38,7 +38,7 @@ using RegX8632::XmmRegister;
using RegX8632::ByteRegister; using RegX8632::ByteRegister;
using RegX8632::X87STRegister; using RegX8632::X87STRegister;
namespace x86 { namespace X8632 {
const int MAX_NOP_SIZE = 8; const int MAX_NOP_SIZE = 8;
...@@ -170,7 +170,7 @@ private: ...@@ -170,7 +170,7 @@ private:
&& ((encoding_[0] & 0x07) == reg); // Register codes match. && ((encoding_[0] & 0x07) == reg); // Register codes match.
} }
friend class AssemblerX86; friend class AssemblerX8632;
}; };
class Address : public Operand { class Address : public Operand {
...@@ -330,20 +330,20 @@ private: ...@@ -330,20 +330,20 @@ private:
// llvm::SmallVector<intptr_t, kMaxUnresolvedBranches> ? // llvm::SmallVector<intptr_t, kMaxUnresolvedBranches> ?
intptr_t unresolved_near_positions_[kMaxUnresolvedBranches]; intptr_t unresolved_near_positions_[kMaxUnresolvedBranches];
friend class AssemblerX86; friend class AssemblerX8632;
}; };
class AssemblerX86 : public Assembler { class AssemblerX8632 : public Assembler {
AssemblerX86(const AssemblerX86 &) = delete; AssemblerX8632(const AssemblerX8632 &) = delete;
AssemblerX86 &operator=(const AssemblerX86 &) = delete; AssemblerX8632 &operator=(const AssemblerX8632 &) = delete;
public: public:
explicit AssemblerX86(bool use_far_branches = false) : Assembler() { explicit AssemblerX8632(bool use_far_branches = false) : Assembler() {
// This mode is only needed and implemented for MIPS and ARM. // This mode is only needed and implemented for MIPS and ARM.
assert(!use_far_branches); assert(!use_far_branches);
(void)use_far_branches; (void)use_far_branches;
} }
~AssemblerX86() override; ~AssemblerX8632() override;
static const bool kNearJump = true; static const bool kNearJump = true;
static const bool kFarJump = false; static const bool kFarJump = false;
...@@ -377,18 +377,19 @@ public: ...@@ -377,18 +377,19 @@ public:
} }
// Operations to emit GPR instructions (and dispatch on operand type). // Operations to emit GPR instructions (and dispatch on operand type).
typedef void (AssemblerX86::*TypedEmitGPR)(Type, GPRRegister); typedef void (AssemblerX8632::*TypedEmitGPR)(Type, GPRRegister);
typedef void (AssemblerX86::*TypedEmitAddr)(Type, const Address &); typedef void (AssemblerX8632::*TypedEmitAddr)(Type, const Address &);
struct GPREmitterOneOp { struct GPREmitterOneOp {
TypedEmitGPR Reg; TypedEmitGPR Reg;
TypedEmitAddr Addr; TypedEmitAddr Addr;
}; };
typedef void (AssemblerX86::*TypedEmitGPRGPR)(Type, GPRRegister, GPRRegister); typedef void (AssemblerX8632::*TypedEmitGPRGPR)(Type, GPRRegister,
typedef void (AssemblerX86::*TypedEmitGPRAddr)(Type, GPRRegister, GPRRegister);
const Address &); typedef void (AssemblerX8632::*TypedEmitGPRAddr)(Type, GPRRegister,
typedef void (AssemblerX86::*TypedEmitGPRImm)(Type, GPRRegister, const Address &);
const Immediate &); typedef void (AssemblerX8632::*TypedEmitGPRImm)(Type, GPRRegister,
const Immediate &);
struct GPREmitterRegOp { struct GPREmitterRegOp {
TypedEmitGPRGPR GPRGPR; TypedEmitGPRGPR GPRGPR;
TypedEmitGPRAddr GPRAddr; TypedEmitGPRAddr GPRAddr;
...@@ -402,9 +403,9 @@ public: ...@@ -402,9 +403,9 @@ public:
TypedEmitGPRImm GPRImm; TypedEmitGPRImm GPRImm;
}; };
typedef void (AssemblerX86::*TypedEmitGPRGPRImm)(Type, GPRRegister, typedef void (AssemblerX8632::*TypedEmitGPRGPRImm)(Type, GPRRegister,
GPRRegister, GPRRegister,
const Immediate &); const Immediate &);
struct GPREmitterShiftD { struct GPREmitterShiftD {
// Technically AddrGPR and AddrGPRImm are also allowed, but in practice // Technically AddrGPR and AddrGPRImm are also allowed, but in practice
// we always normalize Dest to a Register first. // we always normalize Dest to a Register first.
...@@ -412,35 +413,36 @@ public: ...@@ -412,35 +413,36 @@ public:
TypedEmitGPRGPRImm GPRGPRImm; TypedEmitGPRGPRImm GPRGPRImm;
}; };
typedef void (AssemblerX86::*TypedEmitAddrGPR)(Type, const Address &, typedef void (AssemblerX8632::*TypedEmitAddrGPR)(Type, const Address &,
GPRRegister); GPRRegister);
typedef void (AssemblerX86::*TypedEmitAddrImm)(Type, const Address &, typedef void (AssemblerX8632::*TypedEmitAddrImm)(Type, const Address &,
const Immediate &); const Immediate &);
struct GPREmitterAddrOp { struct GPREmitterAddrOp {
TypedEmitAddrGPR AddrGPR; TypedEmitAddrGPR AddrGPR;
TypedEmitAddrImm AddrImm; TypedEmitAddrImm AddrImm;
}; };
// Operations to emit XMM instructions (and dispatch on operand type). // Operations to emit XMM instructions (and dispatch on operand type).
typedef void (AssemblerX86::*TypedEmitXmmXmm)(Type, XmmRegister, XmmRegister); typedef void (AssemblerX8632::*TypedEmitXmmXmm)(Type, XmmRegister,
typedef void (AssemblerX86::*TypedEmitXmmAddr)(Type, XmmRegister, XmmRegister);
const Address &); typedef void (AssemblerX8632::*TypedEmitXmmAddr)(Type, XmmRegister,
const Address &);
struct XmmEmitterRegOp { struct XmmEmitterRegOp {
TypedEmitXmmXmm XmmXmm; TypedEmitXmmXmm XmmXmm;
TypedEmitXmmAddr XmmAddr; TypedEmitXmmAddr XmmAddr;
}; };
typedef void (AssemblerX86::*EmitXmmXmm)(XmmRegister, XmmRegister); typedef void (AssemblerX8632::*EmitXmmXmm)(XmmRegister, XmmRegister);
typedef void (AssemblerX86::*EmitXmmAddr)(XmmRegister, const Address &); typedef void (AssemblerX8632::*EmitXmmAddr)(XmmRegister, const Address &);
typedef void (AssemblerX86::*EmitAddrXmm)(const Address &, XmmRegister); typedef void (AssemblerX8632::*EmitAddrXmm)(const Address &, XmmRegister);
struct XmmEmitterMovOps { struct XmmEmitterMovOps {
EmitXmmXmm XmmXmm; EmitXmmXmm XmmXmm;
EmitXmmAddr XmmAddr; EmitXmmAddr XmmAddr;
EmitAddrXmm AddrXmm; EmitAddrXmm AddrXmm;
}; };
typedef void (AssemblerX86::*TypedEmitXmmImm)(Type, XmmRegister, typedef void (AssemblerX8632::*TypedEmitXmmImm)(Type, XmmRegister,
const Immediate &); const Immediate &);
struct XmmEmitterShiftOp { struct XmmEmitterShiftOp {
TypedEmitXmmXmm XmmXmm; TypedEmitXmmXmm XmmXmm;
...@@ -450,8 +452,9 @@ public: ...@@ -450,8 +452,9 @@ public:
// Cross Xmm/GPR cast instructions. // Cross Xmm/GPR cast instructions.
template <typename DReg_t, typename SReg_t> struct CastEmitterRegOp { template <typename DReg_t, typename SReg_t> struct CastEmitterRegOp {
typedef void (AssemblerX86::*TypedEmitRegs)(Type, DReg_t, SReg_t); typedef void (AssemblerX8632::*TypedEmitRegs)(Type, DReg_t, SReg_t);
typedef void (AssemblerX86::*TypedEmitAddr)(Type, DReg_t, const Address &); typedef void (AssemblerX8632::*TypedEmitAddr)(Type, DReg_t,
const Address &);
TypedEmitRegs RegReg; TypedEmitRegs RegReg;
TypedEmitAddr RegAddr; TypedEmitAddr RegAddr;
...@@ -460,11 +463,11 @@ public: ...@@ -460,11 +463,11 @@ public:
// Three operand (potentially) cross Xmm/GPR instructions. // Three operand (potentially) cross Xmm/GPR instructions.
// The last operand must be an immediate. // The last operand must be an immediate.
template <typename DReg_t, typename SReg_t> struct ThreeOpImmEmitter { template <typename DReg_t, typename SReg_t> struct ThreeOpImmEmitter {
typedef void (AssemblerX86::*TypedEmitRegRegImm)(Type, DReg_t, SReg_t, typedef void (AssemblerX8632::*TypedEmitRegRegImm)(Type, DReg_t, SReg_t,
const Immediate &); const Immediate &);
typedef void (AssemblerX86::*TypedEmitRegAddrImm)(Type, DReg_t, typedef void (AssemblerX8632::*TypedEmitRegAddrImm)(Type, DReg_t,
const Address &, const Address &,
const Immediate &); const Immediate &);
TypedEmitRegRegImm RegRegImm; TypedEmitRegRegImm RegRegImm;
TypedEmitRegAddrImm RegAddrImm; TypedEmitRegAddrImm RegAddrImm;
...@@ -853,34 +856,34 @@ private: ...@@ -853,34 +856,34 @@ private:
Label *GetOrCreateLabel(SizeT Number, LabelVector &Labels); Label *GetOrCreateLabel(SizeT Number, LabelVector &Labels);
}; };
inline void AssemblerX86::EmitUint8(uint8_t value) { inline void AssemblerX8632::EmitUint8(uint8_t value) {
buffer_.Emit<uint8_t>(value); buffer_.Emit<uint8_t>(value);
} }
inline void AssemblerX86::EmitInt16(int16_t value) { inline void AssemblerX8632::EmitInt16(int16_t value) {
buffer_.Emit<int16_t>(value); buffer_.Emit<int16_t>(value);
} }
inline void AssemblerX86::EmitInt32(int32_t value) { inline void AssemblerX8632::EmitInt32(int32_t value) {
buffer_.Emit<int32_t>(value); buffer_.Emit<int32_t>(value);
} }
inline void AssemblerX86::EmitRegisterOperand(int rm, int reg) { inline void AssemblerX8632::EmitRegisterOperand(int rm, int reg) {
assert(rm >= 0 && rm < 8); assert(rm >= 0 && rm < 8);
buffer_.Emit<uint8_t>(0xC0 + (rm << 3) + reg); buffer_.Emit<uint8_t>(0xC0 + (rm << 3) + reg);
} }
inline void AssemblerX86::EmitXmmRegisterOperand(int rm, XmmRegister reg) { inline void AssemblerX8632::EmitXmmRegisterOperand(int rm, XmmRegister reg) {
EmitRegisterOperand(rm, static_cast<GPRRegister>(reg)); EmitRegisterOperand(rm, static_cast<GPRRegister>(reg));
} }
inline void AssemblerX86::EmitFixup(AssemblerFixup *fixup) { inline void AssemblerX8632::EmitFixup(AssemblerFixup *fixup) {
buffer_.EmitFixup(fixup); buffer_.EmitFixup(fixup);
} }
inline void AssemblerX86::EmitOperandSizeOverride() { EmitUint8(0x66); } inline void AssemblerX8632::EmitOperandSizeOverride() { EmitUint8(0x66); }
} // end of namespace x86 } // end of namespace X8632
} // end of namespace Ice } // end of namespace Ice
#endif // SUBZERO_SRC_ASSEMBLER_IA32_H #endif // SUBZERO_SRC_ASSEMBLER_IA32_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment