var arm = {}

// Condition codes
arm.EQ = [0,0,0,0];
arm.NE = [0,0,0,1];
arm.CS = [0,0,1,0];
arm.CC = [0,0,1,1];
arm.MI = [0,1,0,0];
arm.PL = [0,1,0,1];
arm.VS = [0,1,1,0];
arm.VC = [0,1,1,1];
arm.HI = [1,0,0,0];
arm.LS = [1,0,0,1];
arm.GE = [1,0,1,0];
arm.LT = [1,0,1,1];
arm.GT = [1,1,0,0];
arm.LE = [1,1,0,1];
arm.AL = [1,1,1,0];
arm.NV = [1,1,1,1];

// Data processing codes
arm.AND = [0,0,0,0];
arm.EOR = [0,0,0,1];
arm.SUB = [0,0,1,0];
arm.RSB = [0,0,1,1];
arm.ADD = [0,1,0,0];
arm.ADC = [0,1,0,1];
arm.SBC = [0,1,1,0];
arm.RSC = [0,1,1,1];
arm.TST = [1,0,0,0];
arm.TEQ = [1,0,0,1];
arm.CMP = [1,0,1,0];
arm.CMN = [1,0,1,1];
arm.ORR = [1,1,0,0];
arm.MOV = [1,1,0,1];
arm.BIC = [1,1,1,0];
arm.MVN = [1,1,1,1];

arm.R0  = [0,0,0,0];
arm.R1  = [0,0,0,1];
arm.R2  = [0,0,1,0];
arm.R3  = [0,0,1,1];
arm.R4  = [0,1,0,0];
arm.R5  = [0,1,0,1];
arm.R6  = [0,1,1,0];
arm.R7  = [0,1,1,1];
arm.R8  = [1,0,0,0];
arm.R9  = [1,0,0,1];
arm.R10 = [1,0,1,0];
arm.R11 = [1,0,1,1];
arm.R12 = [1,1,0,0];
arm.R13 = [1,1,0,1];
arm.R14 = [1,1,1,0];
arm.R15 = [1,1,1,1];
arm.SL  = arm.R10;
arm.FP  = arm.R11;
arm.IP  = arm.R12;
arm.SP  = arm.R13;
arm.LR  = arm.R14;
arm.PC  = arm.R15;

function ARMAssembler(image) {
  this.image = image;
  return this;
}

ARMAssembler.prototype.label = function(name) {
  this.image.label(name);
  return this;
}

ARMAssembler.prototype.moveRsRd = function(rs, rd) {
  var image = this.image;
  image.emit32(b2d(arm.AL.concat([0,0,0])
                         .concat(arm.MOV)
                         .concat([0])
                         .concat([0,0,0,0])
                         .concat(rd)
                         .concat([0,0,0,0,0,0,0,0])
                         .concat(rs)));
  return this;
}

ARMAssembler.prototype.stmfd = function(rd, registers) {
  var image = this.image;
  image.emit32(b2d(arm.AL.concat([1,0,0])
                         .concat([1,0,0,1,0])
                         .concat(rd)
                         .concat(registers)));
  return this;
}

ARMAssembler.prototype.sub = function(rs, rd, value) {
  var image = this.image;
  image.emit32(b2d(arm.AL.concat([0,0,1])
                         .concat(arm.SUB)
                         .concat([0])
                         .concat(rs)
                         .concat(rd)
                         .concat([0,0,0,0,0,0,0,0,0,0,0,0])) + value);
  return this;
}

ARMAssembler.prototype.moveImmediate = function(value, rd) {
  var image = this.image;
  image.emit32(b2d(arm.AL.concat([0,0,1])
                         .concat(arm.MOV)
                         .concat([0])
                         .concat([0,0,0,0])
                         .concat(rd)
                         .concat([0,0,0,0,0,0,0,0,0,0,0,0])) + value);
  return this;
}

ARMAssembler.prototype.ldmfd = function(rd, registers) {
  var image = this.image;
  image.emit32(b2d(arm.AL.concat([1,0,0])
                         .concat([0,1,0,0,1])
                         .concat(rd)
                         .concat(registers)));
  return this;
}

