1
2 /* "Species" - a CoreWars evolver. Copyright (C) 2003 'Varfar'
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; either version 1, or (at your option) any later
7 * version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 /* this file implements a lookup for code that is interested in whether something is a branch or not */
20
21 #include "opcode_branch_lookup.hpp"
22 #include "error.hpp"
23
24 #include "species.hpp"
25
26 namespace { // anon
27
28 const struct {
29 unsigned num;
30 MODIFIER lookup[MODIFIER_LAST];
31 } EFFECTIVE_MODIFIER_LOOKUP[OPCODE_LAST] = {
32 {1, { mF, mF, mF,mF, mF, mF, mF}}, // * DAT /* must be 0 */
33 {1, { mF, mF, mF,mF, mF, mF, mF}}, // * SPL,
34 {7, { mF, mA, mB,mAB,mBA, mX, mI}}, // * MOV,
35 {3, { mF, mA, mB,mB, mA, mF, mF}}, // * DJN,
36 {6, { mF, mA, mB,mAB,mBA, mX, mF}}, // * ADD,
37 {3, { mF, mA, mB,mB, mA, mF, mF}}, // * JMZ,
38 {6, { mF, mA, mB,mAB,mBA, mX, mF}}, // * SUB,
39 {7, { mF, mA, mB,mAB,mBA, mX, mI}}, // * SEQ,
40 {7, { mF, mA, mB,mAB,mBA, mX, mI}}, // * SNE,
41 {6, { mF, mA, mB,mAB,mBA, mX, mF}}, // * SLT,
42 {5, { mF, mA, mB,mB, mA, mF, mF}}, // * JMN,
43 {1, { mF, mF, mF,mF, mF, mF, mF}}, // * JMP,
44 {1, { mF, mF, mF,mF, mF, mF, mF}}, // * NOP,
45 {6, { mF, mA, mB,mAB,mBA, mX, mF}}, // * MUL,
46 {6, { mF, mA, mB,mAB,mBA, mX, mF}}, // * MODM,
47 {6, { mF, mA, mB,mAB,mBA, mX, mF}}, // * DIV,
48 {7, { mF, mA, mB,mAB,mBA, mX, mI}}, // LDP,
49 {7, { mF, mA, mB,mAB,mBA, mX, mI}} // STP, /* 18 */
50 };
51
52 } // anon
53
54 const bool
55 OPCODE_IS_BRANCH[OPCODE_LAST] = {
56 false, // DAT, /* must be 0 */
57 true, // SPL,
58 false, // MOV,
59 true, // DJN,
60 false, // ADD,
61 true, // JMZ,
62 false, // SUB,
63 false, // SEQ,
64 false, // SNE,
65 false, // SLT,
66 true, // JMN,
67 true, // JMP,
68 false, // NOP,
69 false, // MUL,
70 false, // MODM,
71 false, // DIV,
72 false, // LDP,
73 false // STP, /* 18 */
74 },
75 OPCODE_IS_SKIP[OPCODE_LAST] = {
76 false, // DAT, /* must be 0 */
77 false, // SPL,
78 false, // MOV,
79 false, // DJN,
80 false, // ADD,
81 false, // JMZ,
82 false, // SUB,
83 true, // SEQ,
84 true, // SNE,
85 true, // SLT,
86 false, // JMN,
87 false, // JMP,
88 false, // NOP,
89 false, // MUL,
90 false, // MODM,
91 false, // DIV,
92 false, // LDP,
93 false // STP, /* 18 */
94 },
95 OPCODE_CONTINUES[OPCODE_LAST] = {
96 false, // DAT, /* must be 0 */
97 true, // SPL,
98 true, // MOV,
99 true, // DJN,
100 true, // ADD,
101 true, // JMZ,
102 true, // SUB,
103 true, // SEQ,
104 true, // SNE,
105 true, // SLT,
106 true, // JMN,
107 false, // JMP,
108 true, // NOP,
109 true, // MUL,
110 true, // MODM,
111 true, // DIV,
112 true, // LDP,
113 true // STP, /* 18 */
114 },
115 OPCODE_IS_BRANCH_OR_SKIP[OPCODE_LAST] = {
116 false, // DAT, /* must be 0 */
117 true, // SPL,
118 false, // MOV,
119 true, // DJN,
120 false, // ADD,
121 true, // JMZ,
122 false, // SUB,
123 true, // SEQ,
124 true, // SNE,
125 true, // SLT,
126 true, // JMN,
127 true, // JMP,
128 false, // NOP,
129 false, // MUL,
130 false, // MODM,
131 false, // DIV,
132 false, // LDP,
133 false // STP, /* 18 */
134 };
135
136 const int
137 NUM_OPCODE_BRANCHES = 5,
138 NUM_OPCODE_SKIPS = 3,
139 NUM_OPCODE_CONTINUES = 16;
140
141 static const char
142 *S_MNEMONIC_OPCODE[OPCODE_LAST] = {
143 "DAT","SPL","MOV","DJN","ADD","JMZ","SUB","SEQ","SNE","SLT","JMN","JMP","NOP","MUL","MOD","DIV","LDP","STP" },
144 *S_MNEMONIC_MODIFIER[MODIFIER_LAST] = {
145 "F","A","B","AB","BA","X","I"},
146 S_MNEMONIC_ADDRMODE[ADDRMODE_LAST] = {
147 '$','#','@','<','>','*','{','}'};
148
MNEMONIC_OPCODE(const OPCODE opcode)149 const char *MNEMONIC_OPCODE(const OPCODE opcode) {
150 if(safety_checks) {
151 if((opcode < 0) || (opcode > OPCODE_LAST))
152 PANIC(MISC,"opcode out of range",NULL);
153 }
154 return S_MNEMONIC_OPCODE[opcode];
155 }
156
MNEMONIC_MODIFIER(const MODIFIER modifier)157 const char *MNEMONIC_MODIFIER(const MODIFIER modifier) {
158 if(safety_checks) {
159 if((modifier < 0) || (modifier >MODIFIER_LAST))
160 PANIC(MISC,"modifier out of range",NULL);
161 }
162 return S_MNEMONIC_MODIFIER[modifier];
163 }
164
MNEMONIC_ADDRMODE(const ADDRMODE addrmode)165 const char MNEMONIC_ADDRMODE(const ADDRMODE addrmode) {
166 if(safety_checks) {
167 if((addrmode < 0) || (addrmode > ADDRMODE_LAST))
168 PANIC(MISC,"addrmode out of range",NULL);
169 }
170 return S_MNEMONIC_ADDRMODE[addrmode];
171 }
172
EFFECTIVE_MODIFIER(const OPCODE opcode,const MODIFIER modifier)173 MODIFIER EFFECTIVE_MODIFIER(const OPCODE opcode,const MODIFIER modifier) {
174 MODIFIER ret = modifier;
175 if(safety_checks) {
176 if(opcode > OPCODE_LAST)
177 PANIC(MISC,"opcode out of range",NULL);
178 if(modifier > MODIFIER_LAST)
179 PANIC(MISC,"modifier out of range",NULL);
180 }
181 return EFFECTIVE_MODIFIER_LOOKUP[opcode].lookup[modifier];
182 return ret;
183 }
184
EFFECTIVE_MODIFIERS(const OPCODE opcode)185 unsigned EFFECTIVE_MODIFIERS(const OPCODE opcode) {
186 return EFFECTIVE_MODIFIER_LOOKUP[opcode].num;
187 }
188