/ T0 / Opcode.cs
Opcode.cs
  1  /*
  2   * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
  3   *
  4   * Permission is hereby granted, free of charge, to any person obtaining 
  5   * a copy of this software and associated documentation files (the
  6   * "Software"), to deal in the Software without restriction, including
  7   * without limitation the rights to use, copy, modify, merge, publish,
  8   * distribute, sublicense, and/or sell copies of the Software, and to
  9   * permit persons to whom the Software is furnished to do so, subject to
 10   * the following conditions:
 11   *
 12   * The above copyright notice and this permission notice shall be 
 13   * included in all copies or substantial portions of the Software.
 14   *
 15   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 16   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 17   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 18   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 19   * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 20   * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 21   * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 22   * SOFTWARE.
 23   */
 24  
 25  using System;
 26  using System.Collections.Generic;
 27  
 28  abstract class Opcode {
 29  
 30  	internal Opcode()
 31  	{
 32  	}
 33  
 34  	/*
 35  	 * Execute this opcode.
 36  	 */
 37  	internal abstract void Run(CPU cpu);
 38  
 39  	/*
 40  	 * Resolve the target (word reference) for this opcode.
 41  	 */
 42  	internal virtual void ResolveTarget(Word target)
 43  	{
 44  		throw new Exception("Not a call opcode");
 45  	}
 46  
 47  	/*
 48  	 * Resolve the jump offset for this opcode. Displacement is
 49  	 * relative to the address of the opcode that immediately follows
 50  	 * the jump code; thus, 0 implies no jump at all.
 51  	 */
 52  	internal virtual void ResolveJump(int disp)
 53  	{
 54  		throw new Exception("Not a jump opcode");
 55  	}
 56  
 57  	/*
 58  	 * Get the Word that this opcode references; this can happen
 59  	 * only with "call" and "const" opcodes. For all other opcodes,
 60  	 * this method returns null.
 61  	 */
 62  	internal virtual Word GetReference(T0Comp ctx)
 63  	{
 64  		return null;
 65  	}
 66  
 67  	/*
 68  	 * Get the data block that this opcode references; this can happen
 69  	 * only with "const" opcodes. For all other opcodes, this method
 70  	 * returns null.
 71  	 */
 72  	internal virtual ConstData GetDataBlock(T0Comp ctx)
 73  	{
 74  		return null;
 75  	}
 76  
 77  	/*
 78  	 * Test whether this opcode may "fall through", i.e. execution
 79  	 * may at least potentially proceed to the next opcode.
 80  	 */
 81  	internal virtual bool MayFallThrough {
 82  		get {
 83  			return true;
 84  		}
 85  	}
 86  
 87  	/*
 88  	 * Get jump displacement. For non-jump opcodes, this returns 0.
 89  	 */
 90  	internal virtual int JumpDisp {
 91  		get {
 92  			return 0;
 93  		}
 94  	}
 95  
 96  	/*
 97  	 * Get stack effect for this opcode (number of elements added to
 98  	 * the stack, could be negative). For OpcodeCall, this returns
 99  	 * 0.
100  	 */
101  	internal virtual int StackAction {
102  		get {
103  			return 0;
104  		}
105  	}
106  
107  	internal abstract CodeElement ToCodeElement();
108  
109  	/*
110  	 * This method is called for the CodeElement corresponding to
111  	 * this opcode, at gcode[off]; it is used to compute actual
112  	 * byte jump offsets when converting code to C.
113  	 */
114  	internal virtual void FixUp(CodeElement[] gcode, int off)
115  	{
116  	}
117  }