1 |
18 |
umairsiddi |
#--------------------------------------------------------------
|
2 |
|
|
#-- HPC-16 Assembler
|
3 |
|
|
#--------------------------------------------------------------
|
4 |
|
|
#-- project: HPC-16 Microprocessor
|
5 |
|
|
#--
|
6 |
|
|
#-- ANTLR4 parser Listener Util
|
7 |
|
|
#--
|
8 |
|
|
#--
|
9 |
|
|
#--
|
10 |
|
|
#-- Author: M. Umair Siddiqui (umairsiddiqui@opencores.org)
|
11 |
|
|
#---------------------------------------------------------------
|
12 |
|
|
#------------------------------------------------------------------------------------
|
13 |
|
|
#-- --
|
14 |
|
|
#-- Copyright (c) 2015, M. Umair Siddiqui all rights reserved --
|
15 |
|
|
#-- --
|
16 |
|
|
#-- This file is part of HPC-16. --
|
17 |
|
|
#-- --
|
18 |
|
|
#-- HPC-16 is free software; you can redistribute it and/or modify --
|
19 |
|
|
#-- it under the terms of the GNU Lesser General Public License as published by --
|
20 |
|
|
#-- the Free Software Foundation; either version 2.1 of the License, or --
|
21 |
|
|
#-- (at your option) any later version. --
|
22 |
|
|
#-- --
|
23 |
|
|
#-- HPC-16 is distributed in the hope that it will be useful, --
|
24 |
|
|
#-- but WITHOUT ANY WARRANTY; without even the implied warranty of --
|
25 |
|
|
#-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
|
26 |
|
|
#-- GNU Lesser General Public License for more details. --
|
27 |
|
|
#-- --
|
28 |
|
|
#-- You should have received a copy of the GNU Lesser General Public License --
|
29 |
|
|
#-- along with HPC-16; if not, write to the Free Software --
|
30 |
|
|
#-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
|
31 |
|
|
#-- --
|
32 |
|
|
#------------------------------------------------------------------------------------
|
33 |
|
|
|
34 |
|
|
from __future__ import print_function
|
35 |
|
|
import sys
|
36 |
|
|
import re
|
37 |
|
|
import math
|
38 |
|
|
from antlr4.error.Errors import *
|
39 |
|
|
|
40 |
|
|
class MyHPC16ListenerUtil:
|
41 |
|
|
|
42 |
|
|
def __init__(self, fout):
|
43 |
|
|
self.fout = fout
|
44 |
|
|
self.opcode = dict()
|
45 |
|
|
self.regcode = dict()
|
46 |
|
|
self.jcc_opcode = dict()
|
47 |
|
|
self.alu_opcode = dict()
|
48 |
|
|
self.shift_opcode = dict()
|
49 |
|
|
self.setup_opcode()
|
50 |
|
|
self.setup_regcode()
|
51 |
|
|
self.setup_jcc_opcode()
|
52 |
|
|
self.setup_alu_opcode()
|
53 |
|
|
self.setup_shift_opcode()
|
54 |
|
|
|
55 |
|
|
def setup_shift_opcode(self):
|
56 |
|
|
self.shift_opcode["sll"] = '0b000'
|
57 |
|
|
self.shift_opcode["slr"] = '0b001'
|
58 |
|
|
self.shift_opcode["sal"] = '0b010'
|
59 |
|
|
self.shift_opcode["sar"] = '0b011'
|
60 |
|
|
self.shift_opcode["rol"] = '0b100'
|
61 |
|
|
self.shift_opcode["ror"] = '0b101'
|
62 |
|
|
self.shift_opcode["rcl"] = '0b110'
|
63 |
|
|
self.shift_opcode["rcr"] = '0b111'
|
64 |
|
|
|
65 |
|
|
def setup_alu_opcode(self):
|
66 |
|
|
self.alu_opcode["sub"] = '0b000'
|
67 |
|
|
self.alu_opcode["add"] = '0b001'
|
68 |
|
|
self.alu_opcode["sbb"] = '0b010'
|
69 |
|
|
self.alu_opcode["adc"] = '0b011'
|
70 |
|
|
self.alu_opcode["not"] = '0b100'
|
71 |
|
|
self.alu_opcode["and"] = '0b101'
|
72 |
|
|
self.alu_opcode["or "] = '0b110'
|
73 |
|
|
self.alu_opcode["xor"] = '0b111'
|
74 |
|
|
|
75 |
|
|
def setup_regcode(self):
|
76 |
|
|
for i in range(16):
|
77 |
|
|
self.regcode['R'+str(i)] = bin(i)
|
78 |
|
|
self.regcode['r'+str(i)] = bin(i)
|
79 |
|
|
|
80 |
|
|
def setup_jcc_opcode(self):
|
81 |
|
|
self.jcc_opcode ["jo"] = '0b0000'
|
82 |
|
|
self.jcc_opcode ["jno"] = '0b0001'
|
83 |
|
|
self.jcc_opcode ["jb"] = '0b0010'
|
84 |
|
|
self.jcc_opcode ["jnae"] = '0b0010'
|
85 |
|
|
self.jcc_opcode ["jnb"] = '0b0011'
|
86 |
|
|
self.jcc_opcode ["jae"] = '0b0011'
|
87 |
|
|
self.jcc_opcode ["je"] = '0b0100'
|
88 |
|
|
self.jcc_opcode ["jz"] = '0b0100'
|
89 |
|
|
self.jcc_opcode ["jne"] = '0b0101'
|
90 |
|
|
self.jcc_opcode ["jnz"] = '0b0101'
|
91 |
|
|
self.jcc_opcode ["jbe"] = '0b0110'
|
92 |
|
|
self.jcc_opcode ["jna"] = '0b0110'
|
93 |
|
|
self.jcc_opcode ["jnbe"] = '0b0111'
|
94 |
|
|
self.jcc_opcode ["ja"] = '0b0111'
|
95 |
|
|
self.jcc_opcode ["js"] = '0b1000'
|
96 |
|
|
self.jcc_opcode ["jns"] = '0b1001'
|
97 |
|
|
self.jcc_opcode ["jl"] = '0b1100'
|
98 |
|
|
self.jcc_opcode ["jnge"] = '0b1100'
|
99 |
|
|
self.jcc_opcode ["jnl"] = '0b1101'
|
100 |
|
|
self.jcc_opcode ["jge"] = '0b1101'
|
101 |
|
|
self.jcc_opcode ["jle"] = '0b1110'
|
102 |
|
|
self.jcc_opcode ["jng"] = '0b1110'
|
103 |
|
|
self.jcc_opcode ["jnle"] = '0b1111'
|
104 |
|
|
self.jcc_opcode ["jg"] = '0b1111'
|
105 |
|
|
|
106 |
|
|
|
107 |
|
|
def setup_opcode(self):
|
108 |
|
|
self.opcode["mov_reg_reg"] = '0b00000001'
|
109 |
|
|
self.opcode["mov_sp_reg"] = '0b00000010'
|
110 |
|
|
self.opcode["mov_reg_sp"] = '0b00000100'
|
111 |
|
|
|
112 |
|
|
self.opcode["ld_reg_reg"] = '0b00001000'
|
113 |
|
|
self.opcode["ld_reg_reg_imm16"] = '0b00001001'
|
114 |
|
|
self.opcode["ld_reg_sp"] = '0b00001010'
|
115 |
|
|
self.opcode["ld_reg_sp_imm16"] = '0b00001100'
|
116 |
|
|
|
117 |
|
|
self.opcode["st_reg_reg"] = '0b00010000'
|
118 |
|
|
self.opcode["st_reg_reg_imm16"] = '0b00010001'
|
119 |
|
|
self.opcode["st_reg_sp"] = '0b00010010'
|
120 |
|
|
self.opcode["st_reg_sp_imm16"] = '0b00010100'
|
121 |
|
|
|
122 |
|
|
self.opcode["lbzx_reg_reg"] = '0b00011000'
|
123 |
|
|
self.opcode["lbzx_reg_reg_imm16"] = '0b00011100'
|
124 |
|
|
self.opcode["lbsx_reg_reg"] = '0b00011001'
|
125 |
|
|
self.opcode["lbsx_reg_reg_imm16"] = '0b00011101'
|
126 |
|
|
|
127 |
|
|
self.opcode["sb_reg_reg"] = '0b00100001'
|
128 |
|
|
self.opcode["sb_reg_reg_imm16"] = '0b00100010'
|
129 |
|
|
|
130 |
|
|
self.opcode["inc_reg"] = '0b00101000'
|
131 |
|
|
self.opcode["dec_reg"] = '0b00101001'
|
132 |
|
|
|
133 |
|
|
self.opcode["alur"] = '0b00110'
|
134 |
|
|
self.opcode["shiftr"] = '0b00111'
|
135 |
|
|
|
136 |
|
|
self.opcode["cmp_reg_reg"] = '0b01000000'
|
137 |
|
|
self.opcode["test_reg_reg"] = '0b01000101'
|
138 |
|
|
|
139 |
|
|
self.opcode["li_reg_imm16"] = '0b01001001'
|
140 |
|
|
self.opcode["li_sp_imm16"] = '0b01001010'
|
141 |
|
|
|
142 |
|
|
self.opcode["alui"] = '0b01010'
|
143 |
|
|
self.opcode["shifti"] = '0b01011'
|
144 |
|
|
|
145 |
|
|
self.opcode["cmp_reg_imm16"] = '0b01100000'
|
146 |
|
|
self.opcode["test_reg_imm16"] = '0b01100101'
|
147 |
|
|
|
148 |
|
|
self.opcode["sub_sp_imm16"] = '0b01101000'
|
149 |
|
|
self.opcode["add_sp_imm16"] = '0b01101001'
|
150 |
|
|
|
151 |
|
|
self.opcode["push_reg"] = '0b01110000'
|
152 |
|
|
self.opcode["pushf"] = '0b01110001'
|
153 |
|
|
self.opcode["pop_reg"] = '0b01110100'
|
154 |
|
|
self.opcode["popf"] = '0b01110101'
|
155 |
|
|
|
156 |
|
|
self.opcode["acall_reg"] = '0b01111001'
|
157 |
|
|
self.opcode["call_reg"] = '0b01111010'
|
158 |
|
|
self.opcode["call_imm11"] = '0b10000'
|
159 |
|
|
|
160 |
|
|
self.opcode["ret"] = '0b10001'
|
161 |
|
|
self.opcode["int_imm4"] = '0b10010'
|
162 |
|
|
self.opcode["into"] = '0b10011'
|
163 |
|
|
self.opcode["iret"] = '0b10100'
|
164 |
|
|
|
165 |
|
|
self.opcode["ajmp"] = '0b10101001'
|
166 |
|
|
|
167 |
|
|
self.opcode["jmp_reg"] = '0b10101010'
|
168 |
|
|
|
169 |
|
|
self.opcode["jmp_imm11"] = '0b10110'
|
170 |
|
|
|
171 |
|
|
self.opcode["jcc"] = '0b10111'
|
172 |
|
|
|
173 |
|
|
self.opcode["clc"] = '0b11000000'
|
174 |
|
|
self.opcode["stc"] = '0b11000001'
|
175 |
|
|
self.opcode["cmc"] = '0b11000010'
|
176 |
|
|
self.opcode["cli"] = '0b11000100'
|
177 |
|
|
self.opcode["sti"] = '0b11000101'
|
178 |
|
|
|
179 |
|
|
self.opcode["nop"] = '0b11110'
|
180 |
|
|
self.opcode["halt"] = '0b11111'
|
181 |
|
|
|
182 |
|
|
def log_error(self, s):
|
183 |
|
|
print("# ERROR", s, "\n", file=self.fout)
|
184 |
|
|
print(s, "\n", file=sys.stderr)
|
185 |
|
|
raise ParseCancellationException(s)
|
186 |
|
|
|
187 |
|
|
def vld_reg(self, r):
|
188 |
|
|
if not r in self.regcode:
|
189 |
|
|
self.log_error("invalid register ===> %s\n" % dest)
|
190 |
|
|
return False
|
191 |
|
|
else :
|
192 |
|
|
return True
|
193 |
|
|
|
194 |
|
|
def vld_imm_val(self, imm_val, imm_max):
|
195 |
|
|
if imm_val < imm_max:
|
196 |
|
|
return True
|
197 |
|
|
else:
|
198 |
|
|
s = "invalid immediate operand ===> %s\n required a %d-bit value" % (hex(imm_val), int(math.log(imm_max,2)))
|
199 |
|
|
self.log_error(s)
|
200 |
|
|
return False
|
201 |
|
|
|
202 |
|
|
def get_imm_val(self, imm):
|
203 |
|
|
if re.match("0x", imm):
|
204 |
|
|
return int(imm, 16)
|
205 |
|
|
else:
|
206 |
|
|
return int(imm)
|
207 |
|
|
|
208 |
|
|
def write_ins(self, ins):
|
209 |
|
|
print(hex(ins), file=self.fout)
|
210 |
|
|
|
211 |
|
|
def write_info(self, info):
|
212 |
|
|
print(info, file=self.fout)
|
213 |
|
|
|
214 |
|
|
def cleanup(self):
|
215 |
|
|
self.fout.close()
|
216 |
|
|
|