UNPKG

x86

Version:

Generates x86_64 native code from assembly instructions

94 lines (75 loc) 2.9 kB
import * as i from './instruction'; import * as o from './operand'; import * as d from './def'; export enum MODE { REAL = 16, COMPAT, LONG, } export type TOperand = o.Operand|number|o.number64; export abstract class Code { mode: MODE = MODE.LONG; protected ins: i.Instruction[] = []; protected ClassInstruction = i.Instruction; protected insert(def: d.Definition, operands: i.Operands) { // protected insert(def: d.Definition, o1?: o.Operand, o2?: o.Operand, o3?: o.Operand) { // var ins = new this.ClassInstruction(this, def, this.createOperands(o1, o2, o3)); var ins = new this.ClassInstruction(def, operands, this.mode); ins.index = this.ins.length; this.ins.push(ins); return ins; } protected createOperand(operand: TOperand): o.Operand { if(operand instanceof o.Operand) return operand; if(typeof operand === 'number') { var imm = new o.Constant(operand as number); if(imm.size < o.SIZE.DOUBLE) imm.zeroExtend(o.SIZE.DOUBLE); return imm; } if(operand instanceof Array) return new o.Constant(operand as o.number64); throw TypeError(`Not a valid TOperand type: ${operand}`); } protected createOperands(o1?: TOperand, o2?: TOperand, o3?: TOperand): i.Operands { if(!o1) return new i.Operands(); else { var first: o.Operand, second: o.Operand, third: o.Operand; first = this.createOperand(o1); if(first instanceof o.Constant) return new i.Operands(null, null, first); else { if(!o2) return new i.Operands(first); else { second = this.createOperand(o2); if(second instanceof o.Constant) return new i.Operands(first, null, second); else { if(!o3) return new i.Operands(first, second); else { third = this.createOperand(o3); if(third instanceof o.Constant) new i.Operands(first, second, third); else throw TypeError('Third operand must be immediate.'); } } } } } } compile() { var code: number[] = []; for(var ins of this.ins) { ins.write(code); } return code; } add(o1: o.Operand, o2: o.Operand) { var ops = this.createOperands(o1, o2); if(!(ops.dst instanceof o.Register)) throw TypeError(`Destination operand must be a register.`); } nop(size = 1) { } nopw() { return this.nop(2); } nopl() { return this.nop(4); } }