1 #ifndef INSN_H
2 #define INSN_H
3 /* insn.h: Instruction encoding definition
4  * $Id: insn.h,v 1.4 2004/02/22 06:54:24 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 addrmode */
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 #define maMASK mMASK
52 #define mbMASK mMASK
53 
54 /*
55  * Extract the flags of an instruction `in' field
56  */
57 #define get_flags(in) ( ((in)>>flPOS) & flMASK )
58 #define set_flags(in,flags) ( (in) |= ((flags)<<flPOS) )
59 #define clr_flags(in,flags) ( (in) &=~ ((flags)<<flPOS) )
60 
61 
62 /*
63  * OP(o,m,ma,mb): This macro encodes an instruction `in' field
64  *		  from its various components (not flags).
65  *
66  * 	o: opcode
67  *	m: modifier
68  *	ma: a-mode
69  *	mb: b-mode
70  *
71  *  e.g. OP(SPL, mF, DIRECT, BPREDEC )
72  *  is a
73  *       spl.f $  , <
74  */
75 #define _OP(o,m) ( ((o)<<moBITS) | (m) )
76 #define OP( o, m, ma, mb ) ((_OP((o),(m))<<moPOS) | ((mb) << mbPOS) | (ma))
77 
78 
79 /*
80  * Encodings for various fields of the `in' field.
81  *
82  */
83 enum OPCODE {
84   DAT,				/* must be 0 */
85   SPL,
86   MOV,
87   DJN,
88   ADD,
89   JMZ,
90   SUB,
91   SEQ,
92   SNE,
93   SLT,
94   JMN,
95   JMP,
96   NOP,
97   MUL,
98   MODM,
99   DIV,
100   LDP,
101   STP,				/* 18 */
102 	OPCODE_LAST
103 };
104 
105 enum MODIFIER {
106   mF, mA, mB, mAB, mBA, mX, mI, MODIFIER_LAST	/* 7 */
107 };
108 
109 enum ADDRMODE {				/* must start from 0,
110 				   the ordering is important */
111   DIRECT,
112   IMMEDIATE,
113   BINDIRECT,
114   BPREDEC,
115   BPOSTINC,
116   AINDIRECT,
117   APREDEC,
118   APOSTINC,		/* 8 */
119   ADDRMODE_LAST
120 };
121 
122 #define INDIRECT BINDIRECT
123 #define PREDEC   BPREDEC
124 #define POSTINC  BPOSTINC
125 
126 #define INDIR_A(mode) ((mode) >= AINDIRECT)
127 #define RAW_MODE(mode) ((mode) + (INDIRECT-AINDIRECT))
128 
129 /*
130  * flags
131  */
132 enum {
133   flB_START			/* start label */
134 };
135 
136 #define fl_START (1<<flB_START)
137 
138 
139 /* Macros to take things mod CORESIZE
140  *
141  * Mod here is the `mathematical' modulo, with non-negative
142  * results even with x negative.
143  *
144  * MOD(x,M):	x mod CORESIZE
145  * MODS(x,M):	x mod CORESIZE
146  */
147 #define MODS(x,M) ( (int)(x)%(int)(M) >= 0 \
148 		  ? (int)(x)%(int)(M) \
149 		  : (M) + ((int)(x)%(int)(M)) )
150 #define MOD(x,M) ( (x) % (M) )
151 
152 #define MAX_OPCODES _OP(OPCODE_LAST,MODIFIER_LAST)
153 
154 #endif /* INSN_H */
155