private Expression GenerateTestExpression(ConditionOperand cOp, bool invert) { ConditionCode cc = ConditionCode.ALWAYS; string flags = ""; switch (cOp.Code) { case CondCode.F: return(invert ? Constant.True() : Constant.False()); case CondCode.LT: cc = invert ? ConditionCode.GE : ConditionCode.LT; flags = "SV"; break; case CondCode.LE: cc = invert ? ConditionCode.GT : ConditionCode.LE; flags = "SZV"; break; case CondCode.ULE: cc = invert ? ConditionCode.UGT : ConditionCode.ULE; flags = "ZC"; break; case CondCode.OV: cc = invert ? ConditionCode.NO : ConditionCode.OV; flags = "V"; break; case CondCode.MI: cc = invert ? ConditionCode.NS : ConditionCode.SG; flags = "S"; break; case CondCode.Z: cc = invert ? ConditionCode.NE : ConditionCode.EQ; flags = "Z"; break; case CondCode.C: cc = invert ? ConditionCode.UGE : ConditionCode.ULT; flags = "Z"; break; case CondCode.T: return(invert ? Constant.False() : Constant.True()); case CondCode.GE: cc = invert ? ConditionCode.LT : ConditionCode.GE; flags = "SV"; break; case CondCode.GT: cc = invert ? ConditionCode.LE : ConditionCode.GT; flags = "SZV"; break; case CondCode.UGT: cc = invert ? ConditionCode.ULE : ConditionCode.UGT; flags = "ZC"; break; case CondCode.NV: cc = invert ? ConditionCode.OV : ConditionCode.NO; flags = "V"; break; case CondCode.PL: cc = invert ? ConditionCode.SG : ConditionCode.NS; flags = "S"; break; case CondCode.NZ: cc = invert ? ConditionCode.EQ : ConditionCode.NE; flags = "Z"; break; case CondCode.NC: cc = invert ? ConditionCode.ULT : ConditionCode.UGE; flags = "Z"; break; } return(m.Test( cc, binder.EnsureFlagGroup(arch.GetFlagGroup(flags)))); }
private Tlcs900Instruction Decode(byte b, Opcode opcode, string fmt) { var instr = new Tlcs900Instruction { Opcode = opcode, Address = this.addr, }; var ops = new List <MachineOperand>(); MachineOperand op = null; for (int i = 0; i < fmt.Length; ++i) { switch (fmt[i++]) { case ',': continue; case 'C': // condition code var cc = (CondCode)(b & 0xF); if (cc == CondCode.T) { continue; } op = new ConditionOperand(cc); break; case 'A': op = new RegisterOperand(Tlcs900Registers.a); break; case '3': // Immediate encoded in low 3 bits var c = Constant.Create(Size(fmt[1]), imm3Const[b & 7]); SetSize(fmt[1]); op = new ImmediateOperand(c); break; case 'I': // immediate op = Immediate(fmt[i++]); break; case 'j': // Relative jump switch (fmt[i++]) { case 'b': byte o8; if (!rdr.TryReadByte(out o8)) { op = null; } else { op = AddressOperand.Create(rdr.Address + (sbyte)o8); } break; case 'w': short o16; if (!rdr.TryReadLeInt16(out o16)) { op = null; } else { op = AddressOperand.Create(rdr.Address + o16); } break; } break; case 'J': // Absolute jump switch (fmt[i++]) { case 'w': op = AbsoluteDestination(2); break; case 'l': op = AbsoluteDestination(3); break; default: op = null; break; } break; case 'R': // 16 bit register encoded in lsb op = new RegisterOperand(Reg(fmt[i++], b & 0x7)); break; case 'S': // status/flag register op = StatusRegister(fmt[i++]); break; } if (op == null) { return(Decode(b, Opcode.invalid, "")); } ops.Add(op); } if (ops.Count > 0) { instr.op1 = ops[0]; if (ops.Count > 1) { instr.op2 = ops[1]; if (ops.Count > 2) { instr.op3 = ops[2]; } } } return(instr); }
private MachineOperand DecodeOperand(byte b, string fmt) { MachineOperand op; byte r; Constant c; byte o8; int incCode; switch (fmt[0]) { case '+': // Predecrement if (!rdr.TryReadByte(out r)) { return(null); } incCode = r & 3; if (incCode >= incDecSize.Length) { return(null); } op = MemoryOperand.PostIncrement(Size(fmt[1]), incDecSize[r & 3], Reg('x', (r >> 2) & 0x3F)); SetSize(fmt[1]); return(op); case '-': if (!rdr.TryReadByte(out r)) { return(null); } incCode = r & 3; if (incCode >= incDecSize.Length) { return(null); } op = MemoryOperand.PreDecrement(Size(fmt[1]), incDecSize[r & 3], Reg('x', (r >> 2) & 0x3F)); SetSize(fmt[1]); return(op); case '3': // Immediate encoded in low 3 bits c = Constant.Create(Size(fmt[1]), b & 7); SetSize(fmt[1]); return(new ImmediateOperand(c)); case '#': // Immediate encoded in low 3 bits, with 8 encoded as 0 c = Constant.Create(Size(fmt[1]), imm3Const[b & 7]); SetSize(fmt[1]); return(new ImmediateOperand(c)); case 'A': // A register op = new RegisterOperand(Tlcs900Registers.a); return(op); case 'C': // condition code op = new ConditionOperand((CondCode)(b & 0xF)); return(op); case 'I': // immediate op = Immediate(fmt[1]); return(op); case 'j': // Relative jump switch (fmt[1]) { case 'b': if (!rdr.TryReadByte(out o8)) { return(null); } else { return(AddressOperand.Create(rdr.Address + (sbyte)o8)); } case 'w': short o16; if (!rdr.TryReadLeInt16(out o16)) { return(null); } else { return(AddressOperand.Create(rdr.Address + o16)); } } return(null); case 'r': // Register case 'R': //$TODO: 'r' may encode other registers. manual is dense op = new RegisterOperand(Reg(fmt[1], b & 0x7)); SetSize(fmt[1]); return(op); case 'M': // Register indirect op = MemoryOperand.Indirect(Size(fmt[1]), Reg('x', b & 7)); SetSize(fmt[1]); return(op); case 'N': // indexed (8-bit offset) if (!rdr.TryReadByte(out o8)) { return(null); } op = MemoryOperand.Indexed8(Size(fmt[1]), Reg('x', b & 7), (sbyte)o8); SetSize(fmt[1]); return(op); case 'm': // various mem formats byte m; if (!rdr.TryReadByte(out m)) { return(null); } switch (m & 3) { case 0: // Register indirect op = MemoryOperand.Indirect(Size(fmt[1]), Reg('x', (m >> 2) & 0x3F)); break; case 1: // indexed (16-bit offset) short o16; if (!rdr.TryReadLeInt16(out o16)) { return(null); } op = MemoryOperand.Indexed16(Size(fmt[1]), Reg('x', (m >> 2) & 0x3F), o16); SetSize(fmt[1]); return(op); case 3: if (m != 3 && m != 7) { return(null); } byte rBase; if (!rdr.TryReadByte(out rBase)) { return(null); } byte rIdx; if (!rdr.TryReadByte(out rIdx)) { return(null); } var regBase = Reg('x', rBase); var regIdx = Reg(m == 3 ? 'b' : 'w', rIdx); op = MemoryOperand.RegisterIndexed(Size(fmt[1]), regBase, regIdx); SetSize(fmt[1]); return(op); default: throw new FormatException(string.Format( "Unknown format {0} decoding bytes {1:X2}{2:X2}.", fmt[0], (int)b, (int)m)); } SetSize(fmt[1]); return(op); case 'O': return(Absolute(1, fmt[1])); case 'P': return(Absolute(2, fmt[1])); case 'Q': return(Absolute(3, fmt[1])); default: throw new FormatException( string.Format( "Unknown format {0} decoding byte {1:X2}.", fmt[0], (int)b)); } }