public override void Assemble(Assembler assembler) { if (RegDst is ValReg32) throw new AssembleException(ErrorMessage.NotSupported); assembler.Add(AsmMov.Create(RegDst.Index, RegSrc)); assembler.Add(Instruction.CreateInstance(MetaInfo.InstructionType, RegDst.Index) as Instruction); }
public override void Assemble(Assembler assembler) { assembler.Add(AsmBranch.Create()); assembler.ElseMapping[this] = assembler.Last() as AsmBranch; assembler.Add(AsmEmpty.Create()); assembler.IfMapping[If].Target = assembler.Last(); }
public static void CopyFromStackToIX(Assembler assembler, int size, int ixOffset = 0, bool restoreIX = false) { int changeToIX = 0; var totalBytesToCopy = size; int originalIxOffset = ixOffset; do { var bytesToCopy = totalBytesToCopy > 2 ? 2 : totalBytesToCopy; // offset has to be -128 to + 127 while (ixOffset + bytesToCopy > 128) { // Need to move IX along to keep stackOffset within -128 to +127 range assembler.Ld(R16.DE, 127); assembler.Add(I16.IX, R16.DE); changeToIX += 127; ixOffset -= 127; size -= 127; } while (ixOffset < -128) { assembler.Ld(R16.DE, -128); assembler.Add(I16.IX, R16.DE); changeToIX -= 128; ixOffset += 128; size += 128; } switch (bytesToCopy) { case 1: assembler.Pop(R16.HL); assembler.Ld(I16.IX, (short)(ixOffset + 0), R8.L); break; case 2: case 4: assembler.Pop(R16.HL); assembler.Ld(I16.IX, (short)(ixOffset + 1), R8.H); assembler.Ld(I16.IX, (short)(ixOffset + 0), R8.L); break; } ixOffset += 2; totalBytesToCopy -= 2; } while (ixOffset < size + originalIxOffset); if (changeToIX != 0 && restoreIX) { assembler.Ld(R16.DE, (short)(-changeToIX)); assembler.Add(I16.IX, R16.DE); } }
private void GenerateProlog(Assembler assembler) { // Stack frame looks like this: // // | | // |-----------------------| // | incoming | // | arguments | // |-----------------------| // | return address | // +=======================+ // | IX (optional) | Not present if no locals or params // |-----------------------| <-- IX will point to here when method code executes // | Local variables | // |-----------------------| // | Arguments for the | // ~ next method ~ // | | // | | | // | | Stack grows | // | downward // V var localsSize = 0; var tempCount = 0; foreach (var localVariable in _context.LocalVariableTable) { if (localVariable.IsTemp) { tempCount++; } if (!localVariable.IsParameter) { localsSize += localVariable.ExactSize; } } if (_context.ParamsCount > 0 || (_context.LocalsCount + tempCount) > 0) { assembler.Push(I16.IX); assembler.Ld(I16.IX, 0); assembler.Add(I16.IX, R16.SP); } if (_context.LocalsCount + tempCount > 0) { // Reserve space on stack for locals assembler.Ld(R16.HL, (short)-localsSize); assembler.Add(R16.HL, R16.SP); assembler.Ld(R16.SP, R16.HL); } }
public override void Assemble(Assembler assembler) { if (Count is ValReg) { assembler.Add(AsmMov.Create(Assembler.IReg, (int)((Count as ValReg).Index << 4))); assembler.Add(AsmStoreOp.Create(Assembler.IReg)); } else if (Count is ValReg32) { throw new AssembleException(ErrorMessage.NotSupported); } assembler.Add(AsmFor.Create()); assembler.ForMapping[this] = assembler.Last() as AsmFor; }
public override void Assemble(Assembler assembler) { if (Right is ValInstant) { assembler.Add(AsmMov.Create(Assembler.IReg, Right)); assembler.Add(Operater.Assemble(Left.Index, Assembler.IReg)); } else { assembler.Add(Operater.Assemble(Left.Index, (Right as ValReg).Index)); } assembler.Add(AsmBranchFalse.Create()); assembler.IfMapping[this] = assembler.Last() as AsmBranchFalse; }
public static void CopyFromIXToStack(Assembler assembler, int size, int ixOffset = 0, bool restoreIX = false) { int changeToIX = 0; int originalIxOffset = ixOffset; ixOffset += size - 2; do { var bytesToCopy = size > 2 ? 2 : size; size -= 2; if (ixOffset + bytesToCopy < -127) { var delta = ixOffset + 1; assembler.Ld(R16.DE, (short)delta); assembler.Add(I16.IX, R16.DE); changeToIX += delta; ixOffset -= delta; originalIxOffset -= delta; } switch (bytesToCopy) { case 1: assembler.Ld(R8.H, 0); assembler.Ld(R8.L, I16.IX, (short)(ixOffset + 1)); assembler.Push(R16.HL); break; case 2: case 4: assembler.Ld(R8.H, I16.IX, (short)(ixOffset + 1)); assembler.Ld(R8.L, I16.IX, (short)(ixOffset + 0)); assembler.Push(R16.HL); break; } ixOffset -= 2; } while (ixOffset >= originalIxOffset); if (changeToIX != 0 && restoreIX) { assembler.Ld(R16.DE, (short)(-changeToIX)); assembler.Add(I16.IX, R16.DE); } }
public override void Assemble(Assembler assembler) { if (Duration is ValReg) { assembler.Add(AsmStoreOp.Create((Duration as ValReg).Index)); assembler.Add(AsmWait.Create(0)); } else if (Duration is ValInstant) { assembler.Add(AsmWait.Create((Duration as ValInstant).Val)); } else { throw new AssembleException(ErrorMessage.NotSupported); } }
public override void Assemble(Assembler assembler) { if (Level.Val <= 0) { return; } assembler.Add(AsmContinue.Create(0, Level.Val - 1)); }
public override void Assemble(Assembler assembler) { if (RegDst is ValReg32) { throw new AssembleException(ErrorMessage.NotSupported); } assembler.Add(AsmMov.Create(RegDst.Index, Value)); }
public override void Assemble(Assembler assembler) { if (Value is ValInstant) { assembler.Add(AsmMov.Create(Assembler.IReg, -(Value as ValInstant).Val)); assembler.Add(AsmAdd.Create(RegDst.Index, new ValReg(Assembler.IReg))); } else if (Value is ValReg) { assembler.Add(AsmMov.Create(Assembler.IReg, Value)); assembler.Add(AsmNegative.Create(Assembler.IReg)); assembler.Add(AsmAdd.Create(RegDst.Index, new ValReg(Assembler.IReg))); } else { throw new AssembleException(ErrorMessage.NotSupported); } }
public override void Assemble(Assembler assembler) { int val = 0; if (For.Count is ValInstant) { val = (For.Count as ValInstant).Val; } assembler.Add(AsmNext.Create(val)); assembler.ForMapping[For].Next = assembler.Last() as AsmNext; }
public override void Assemble(Assembler assembler) { assembler.Add(AsmEmpty.Create()); if (If.Else == null) { assembler.IfMapping[If].Target = assembler.Last(); } else { assembler.ElseMapping[If.Else].Target = assembler.Last(); } }
public override void Assemble(Assembler assembler) { if (RegIter is ValReg32) { throw new AssembleException(ErrorMessage.NotSupported); } assembler.Add(AsmMov.Create(RegIter.Index, InitVal)); uint e_val = RegIter.Index; if (Count is ValReg) { e_val |= (Count as ValReg).Index << 4; } else if (Count is ValReg32) { throw new AssembleException(ErrorMessage.NotSupported); } assembler.Add(AsmMov.Create(Assembler.IReg, (int)e_val)); assembler.Add(AsmStoreOp.Create(Assembler.IReg)); assembler.Add(AsmFor.Create()); assembler.ForMapping[this] = assembler.Last() as AsmFor; }
private IntPtr CreateMethodStub(MethodCompiler methodCompiler) { if (methodCompiler == null) throw new ArgumentNullException("methodCompiler"); _unmanagedDelegates.Add(methodCompiler); IntPtr methodPtr = Marshal.GetFunctionPointerForDelegate(methodCompiler); Assembler assembler = new Assembler(); Label label = assembler.DefineLabel(); assembler.Call(label); assembler.MarkLabel(label); assembler.Sub(Mem.sysint_ptr(Register.nsp), 5); assembler.Call(methodPtr); assembler.Add(Register.nsp, IntPtr.Size); assembler.Jmp(Register.nax); return assembler.Make(); }
private static IntPtr CreateCompilerLaunchPad() { Console.Error.WriteLine("Creating the compiler launch pad:"); Console.Error.WriteLine(); MethodCompiler methodCompiler = CreateMethod; _unmanagedDelegates.Add(methodCompiler); IntPtr methodPtr = Marshal.GetFunctionPointerForDelegate(methodCompiler); Assembler assembler = new Assembler(); assembler.Logger = new FileLogger(Console.Error); assembler.Push(Register.nbp); assembler.Mov(Register.nbp, Register.nsp); if (IntPtr.Size == 4) { assembler.Push(Mem.dword_ptr(Register.nbp, 4)); assembler.Sub(Mem.dword_ptr(Register.nsp), 5); } else { assembler.Push(Register.ncx); assembler.Mov(Register.ncx, Mem.qword_ptr(Register.nbp, 8)); assembler.Sub(Register.ncx, 5); } assembler.Call(methodPtr); if (IntPtr.Size == 4) { assembler.Add(Register.nsp, 4); } else { assembler.Pop(Register.ncx); } assembler.Pop(Register.nbp); assembler.Ret(); return assembler.Make(); }
/// <summary> /// Creates a call to the given handler /// </summary> /// <param name="assembler">The assembler</param> /// <param name="callingConventions">The calling conventions</param> /// <param name="handlerFunction">The handler function to call</param> private int CreateHandlerCall(Assembler assembler, CallingConventions callingConventions, RuntimeInterface.RuntimeErrorDelegate handlerFunction) { var handlerOffset = assembler.GeneratedCode.Count; int shadowSpace = callingConventions.CalculateShadowStackSize(); if (shadowSpace > 0) { assembler.Sub(Register.SP, shadowSpace); } var handlerFunctionPointer = Marshal.GetFunctionPointerForDelegate(handlerFunction); assembler.Move(Register.R11, handlerFunctionPointer.ToInt64()); assembler.CallInRegister(Register.R11); if (shadowSpace > 0) { assembler.Add(Register.SP, shadowSpace); } return(handlerOffset); }
public override void Assemble(Assembler assembler) { int keycode = Key.KeyCode; int dindex = Assembler.GetDirectionIndex(Key); if (Duration is ValRegEx) { if (Duration is ValReg32) { throw new AssembleException(ErrorMessage.NotSupported); } var reg = Duration as ValRegEx; assembler.Add(AsmStoreOp.Create(reg.Index)); assembler.Add(AsmStick_Standard.Create(keycode, dindex, 0)); ReleasePrevious(assembler); } else if (Duration is ValInstant) { int duration = (Duration as ValInstant).Val; var ins = AsmStick_Standard.Create(keycode, dindex, duration); if (ins.Success) { assembler.Add(ins); ReleasePrevious(assembler); } else if (ins == Instruction.Failed.OutOfRange) { assembler.Add(AsmStick_Hold.Create(keycode, dindex)); ReleasePrevious(assembler); assembler.StickMapping[keycode] = assembler.Last() as AsmStick_Hold; assembler.Add(AsmWait.Create(duration)); assembler.Add(AsmEmpty.Create()); ReleasePrevious(assembler); } } else { throw new AssembleException(ErrorMessage.NotImplemented); } }
public override void Assemble(Assembler assembler) { assembler.Add(AsmKey_Hold.Create(Key.KeyCode)); ReleasePrevious(assembler); assembler.KeyMapping[Key.KeyCode] = assembler.Last() as AsmKey_Hold; }
public override void Assemble(Assembler assembler) { assembler.Add(Instruction.CreateInstance(MetaInfo.InstructionType, RegDst.Index, Value) as Instruction); }
public override void Assemble(Assembler assembler) { assembler.Add(AsmSerialPrint.Create(Mem ? 1u : 0, Value)); }
public override void Assemble(Assembler assembler) { assembler.Add(AsmStick_Hold.Create(Key.KeyCode, Assembler.GetDirectionIndex(Key))); ReleasePrevious(assembler); assembler.StickMapping[Key.KeyCode] = assembler.Last() as AsmStick_Hold; }
public override void Assemble(Assembler assembler) { assembler.Add(AsmEmpty.Create()); ReleasePrevious(assembler); }
public override void Assemble(Assembler assembler) { assembler.Add(AsmFor.Create()); assembler.ForMapping[this] = assembler.Last() as AsmFor; }