1 #ifndef INSN_H
2 #define INSN_H
3 /* insn.h: Instruction encoding definition
4  * $Id: insn.h,v 1.1.1.1 2003/08/26 16:57:02 varfar Exp $
5  */
6 
7 /* This file is part of `exhaust', a memory array redcode simulator.
8  * Copyright (C) 2002 M Joonas Pihlaja
9  * Public Domain.
10  */
11 
12 /*
13  * Instruction encoding:
14  *
15  * Instructions are held in a insn_t typed struct with three fields:
16  *   in:	instruction flags, opcode, modifier, a-mode, b-mode
17  *   a:		a-value
18  *   b: 	b-value
19  *
20  * The layout of the `in' field is as follows:
21  *
22  * bit         15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
23  * field   | flags | |- op-code  -| |-.mod-| |b-mode| |a-mode|
24  *
25  * Currently there is only one flag, the fl_START flag, which
26  * the assembler uses to figure out the starting instruction
27  * of a warrior (i.e. the one given by the START label).
28  */
29 
30 #define mBITS 3			/* number of bits for mode */
31 #define opBITS 5		/* bits for opcode */
32 #define moBITS 3		/* bits for modifier */
33 #define flBITS 2		/* bits for flags */
34 
35 /* Positions of various fields
36  */
37 #define maPOS 0
38 #define mbPOS (maPOS + mBITS)
39 #define moPOS (mbPOS + mBITS)
40 #define opPOS (moPOS + moBITS)
41 #define flPOS (opPOS + opBITS)
42 
43 /* Various masks.  These extract a field once it has been
44  * shifted to the least significant bits of the word.
45  */
46 #define moMASK ((1<<moBITS)-1)
47 #define opMASK ((1<<opBITS)-1)
48 #define mMASK ((1<<mBITS)-1)
49 #define flMASK ((1<<flBITS)-1)
50 #define iMASK ( (1<<flPOS)-1 )
51 
52 /*
53  * Extract the flags of an instruction `in' field
54  */
55 #define get_flags(in) ( ((in)>>flPOS) & flMASK )
56 #define set_flags(in,flags) ( (in) |= ((flags)<<flPOS) )
57 #define clr_flags(in,flags) ( (in) &=~ ((flags)<<flPOS) )
58 
59 
60 /*
61  * OP(o,m,ma,mb): This macro encodes an instruction `in' field
62  *		  from its various components (not flags).
63  *
64  * 	o: opcode
65  *	m: modifier
66  *	ma: a-mode
67  *	mb: b-mode
68  *
69  *  e.g. OP(SPL, mF, DIRECT, BPREDEC )
70  *  is a
71  *       spl.f $  , <
72  */
73 #define _OP(o,m) ( ((o)<<moBITS) | (m) )
74 #define OP( o, m, ma, mb ) ((_OP((o),(m))<<moPOS) | ((mb) << mbPOS) | (ma))
75 
76 
77 /*
78  * Encodings for various fields of the `in' field.
79  *
80  */
81 enum OPCODE {
82   DAT,				/* must be 0 */
83   SPL,
84   MOV,
85   DJN,
86   ADD,
87   JMZ,
88   SUB,
89   SEQ,
90   SNE,
91   SLT,
92   JMN,
93   JMP,
94   NOP,
95   MUL,
96   MODM,
97   DIV,
98   LDP,
99   STP,				/* 18 */
100   OPCODE_LAST
101 };
102 
103 enum MODIFIER {
104   mF, mA, mB, mAB, mBA, mX, mI,	/* 7 */
105   MODIFIER_LAST
106 };
107 
108 enum ADDRMODE {				/* must start from 0,
109 				   the ordering is important */
110   DIRECT,
111   IMMEDIATE,
112   BINDIRECT,
113   BPREDEC,
114   BPOSTINC,
115   AINDIRECT,
116   APREDEC,
117   APOSTINC,		/* 8 */
118   ADDRMODE_LAST
119 };
120 
121 #define INDIRECT BINDIRECT
122 #define PREDEC   BPREDEC
123 #define POSTINC  BPOSTINC
124 
125 #define INDIR_A(mode) ((mode) >= AINDIRECT)
126 #define RAW_MODE(mode) ((mode) + (INDIRECT-AINDIRECT))
127 
128 /*
129  * flags
130  */
131 enum {
132   flB_START			/* start label */
133 };
134 
135 #define fl_START (1<<flB_START)
136 
137 
138 /* Macros to take things mod CORESIZE
139  *
140  * Mod here is the `mathematical' modulo, with non-negative
141  * results even with x negative.
142  *
143  * MOD(x,M):	x mod CORESIZE
144  * MODS(x,M):	x mod CORESIZE
145  */
146 #define MODS(x,M) ( (int)(x)%(int)(M) >= 0 \
147 		  ? (int)(x)%(int)(M) \
148 		  : (M) + ((int)(x)%(int)(M)) )
149 #define MOD(x,M) ( (x) % (M) )
150 
151 #endif /* INSN_H */
152