OpenCores
URL https://opencores.org/ocsvn/ssbcc/ssbcc/trunk

Subversion Repositories ssbcc

[/] [ssbcc/] [trunk/] [core/] [9x8/] [asm] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sinclairrf
#!/usr/bin/python2.7
2
 
3
################################################################################
4
#
5
# Copyright 2012, Sinclair R.F., Inc.
6
#
7
# Assembler for SSBCC 9x8 processor
8
#
9
################################################################################
10
 
11
# global modules
12
import argparse
13
import re
14
import sys
15
 
16
# User defined modules
17
import asmDef
18
 
19
################################################################################
20
#
21
# Surround the program with a try ... except clause
22
#
23
################################################################################
24
 
25
try:
26
 
27
  ################################################################################
28
  #
29
  # The main loop:
30
  #
31
  # - Process the command line arguments.
32
  #
33
  ################################################################################
34
 
35
  #
36
  # Construct the command-line argument list parser
37
  #
38
 
39
  def validateFile(filename):
40
    try:
41
      return file(filename,'r');
42
    except:
43
      raise asmDef.AsmException('Error opening "%s"' % filename);
44
 
45
  argListParser = argparse.ArgumentParser(description='SSBCC 9x8 assembler');
46
  argListParser.add_argument('-C', metavar='CONSTANT=value', action='append', help='Constant definition');
47
  argListParser.add_argument('-G', metavar='parametername', action='append', help='parameter names');
48
  argListParser.add_argument('-I', metavar='PORT=index', action='append', help='Input port names');
49
  argListParser.add_argument('-L', metavar='librarypath', action='append', help='Library search path');
50 3 sinclairrf
  argListParser.add_argument('-M', metavar='macropath', action='append', help='Macro search path');
51 2 sinclairrf
  argListParser.add_argument('-O', metavar='PORT=index', action='append', help='Output port names');
52
  argListParser.add_argument('-R', metavar='PORT=index', action='append', help='Strobe-only output port names');
53
  argListParser.add_argument('-S', metavar='MEMORY=length', action='append', help='Memory length');
54
  argListParser.add_argument('-i', action='store_true', help='enable/require interrupt');
55
  argListParser.add_argument('-o', metavar='outfile', type=argparse.FileType('w'), required =True, help='output metafile');
56
  argListParser.add_argument('-s', metavar='STACK_NAME=length', action='append', help='Stack length');
57
  argListParser.add_argument('filename', metavar='filename', nargs='+', type=validateFile, help='required list of files');
58
  argList = argListParser.parse_args();
59
 
60
  # Construct the keyword parser
61
  from asmDef_9x8 import asmDef_9x8
62
  ad = asmDef_9x8();
63
 
64
  # Record the constants in the program symbol table.
65
  if argList.C:
66
    for constant in argList.C:
67
      a=re.findall(r'^(C_\w+)=(\w+)$',constant);
68
      if not a:
69
        raise asmDef.AsmException('Malformed -C argument: "%s"' % constant);
70
      a = list(a[0]);
71
      try:
72
        a[1] = eval(a[1]);
73
      except:
74
        raise asmDef.AsmException('Cannot evaluate "%s"' % a[1]);
75
      if ad.IsSymbol(a[0]):
76
        raise asmDef.AsmException('Command line constant "%s" already defined' % a[0]);
77
      ad.AddSymbol(a[0], 'constant', body=[a[1]]);
78
 
79
  # Record the input names and values in the appropriate record type
80
  if argList.G:
81
    for parameter in argList.G:
82
      a = re.findall(r'^([LG]_\w+)$',parameter);
83
      if not a:
84
        raise asmDef.AsmException('Malformed -G argument: "%s"' % parameter);
85
      if ad.IsSymbol(a[0]):
86
        raise asmDef.AsmException('Program Bug -- repeated symbol "%s"' % a[0]);
87
      ad.RegisterParameterName(a[0]);
88
  if argList.I:
89
    for inport in argList.I:
90
      a=re.findall(r'^(I_\w+)=(0|[1-9]\d*)$',inport);
91
      if not a:
92
        raise asmDef.AsmException('Malformed -I argument: "%s"' % inport);
93
      a = a[0];
94
      if ad.IsSymbol(a[0]):
95
        raise Exception('Program Bug -- repeated symbol "%s"' % a[0]);
96
      ix = int(a[1]);
97
      if not (0 <= ix < 256):
98
        raise asmDef.AsmException('Out-of-range inport index:  "%s"' % inport);
99
      ad.RegisterInport(a[0],ix);
100
  if argList.O:
101
    for outport in argList.O:
102
      a=re.findall(r'^(O_\w+)=(0|[1-9]\d*)$',outport);
103
      if not a:
104
        raise asmDef.AsmException('Malformed -O argument: "%s"' % outport);
105
      a = a[0];
106
      if ad.IsSymbol(a[0]):
107
        raise asmDef.AsmException('Program Bug -- repeated symbol "%s"' % a[0]);
108
      ix = int(a[1]);
109
      if not (0 <= ix < 256):
110
        raise asmDef.AsmException('Out-of-range outport index:  "%s"' % outport);
111
      ad.RegisterOutport(a[0],ix);
112
  if argList.R:
113
    for outstrobe in argList.R:
114
      a=re.findall(r'^(O_\w+)=(0|[1-9]\d*)$',outstrobe);
115
      if not a:
116
        raise asmDef.AsmException('Malformed -R argument: "%s"' % outstrobe);
117
      a = a[0];
118
      if ad.IsSymbol(a[0]):
119
        raise asmDef.AsmException('Program Bug -- repeated symbol "%s"' % a[0]);
120
      ix = int(a[1]);
121
      if not (0 <= ix < 256):
122
        raise asmDef.AsmException('Out-of-range strobe-only outport index:  "%s"' % outstrobe);
123
      ad.RegisterOutstrobe(a[0],ix);
124
  if argList.S:
125
    for memory in argList.S:
126
      a=re.findall(r'^(\w+)=(0|[1-9]\d*)$',memory);
127
      if not a:
128
        raise asmDef.AsmException('Malformed -S argument: "%s"' % memory);
129
      a=a[0];
130
      length = int(a[1]);
131
      if not (0 < length <= 256):
132
        raise asmDef.AsmException('Out-of-range memory length:  "%s"' % outport);
133
      ad.RegisterMemoryLength(a[0],length);
134
  if argList.s:
135
    for stack in argList.s:
136
      a=re.findall(r'^(\w+)=(0|[1-9]\d*)$',stack);
137
      if not a:
138
        raise asmDef.AsmException('Malformed -s argument: "%s"' % stack);
139
      a = a[0];
140
      ad.RegisterStackLength(a[0],int(a[1]));
141
 
142
  # Construct the iterator that loops through the code bodies.
143
  fbi = asmDef.FileBodyIterator(argList.filename,ad);
144 3 sinclairrf
 
145
  # Add paths for the ".include" directive.
146 2 sinclairrf
  if argList.L:
147
    for path in argList.L:
148
      fbi.AddSearchPath(path);
149
 
150 3 sinclairrf
  # Add paths for the ".macro" directive.
151
  if argList.M:
152
    for path in argList.M:
153
      ad.AddMacroSearchPath(path);
154
 
155 2 sinclairrf
  ################################################################################
156
  #
157
  # Stage 1:  Parse the files.
158
  #
159
  # Read the entire file, doing the following while reading the file:
160
  # - Store the raw content of each line or group of lines for output to the
161
  #   assembled memory initialization.
162
  #   Note: A group of lines consists the comment lines preceding a directive and
163
  #         the body of the directive.
164
  # - Convert group of lines into an array of the raw tokens.
165
  # - Check the integrity of the bodies defined by the list of raw tokens.
166
  # - For each array of raw tokens, incorporate already-defined symbols and update
167
  #   the assembler dictionaries.
168
  #   Note: At this point the space required for the function or main program
169
  #     is fully computed.
170
  #
171
  ################################################################################
172
 
173
  #
174
  # Loop through the directive bodies in the input files (including ".include"d
175
  # files).
176
  #
177
 
178
  ifstackStack = list();
179
  ifstack = None;
180
  for bl in fbi:
181
    filename = bl[0];
182
    startLine = bl[1];
183
    body = bl[2:];
184
    flc_loc = filename + ' at line ' + str(startLine+len(body)-1);
185
    # Start-of-file processing.
186
    if startLine == 0:
187
      if ifstack != None:
188
        ifstackStack.append(ifstack);
189
      ifstack = list();
190
    # End-of-file processing.
191
    elif startLine == -1:
192
      if len(ifstack) != 0:
193
        raise asmDef.AsmException('%d unmatched .IFDEF/.IFNDEF(s) at the end of %s' % (len(ifstack),filename,));
194
      if ifstackStack:
195
        ifstack = ifstackStack.pop();
196
      else:
197
        ifstack = None;
198
    # Handle conditional compilation directives.
199
    elif re.match(r'\s*\.ELSE\b',body[-1]):
200
      if not re.match(r'\s*\.ELSE\s*(;.*)?$',body[-1]):
201
        raise asmDef.AsmException('Malformed ".ELSE" in %s' % flc_loc);
202
      if not ifstack:
203
        raise asmDef.AsmException('Unmatched ".ELSE" in %s' % flc_loc);
204
      ifstack[-1] ^= True;
205
    elif re.match(r'\s*\.ENDIF\b',body[-1]):
206
      if not re.match(r'\s*\.ENDIF\s*(;.*)?$',body[-1]):
207
        raise asmDef.AsmException('Malformed ".ENDIF" in %s' % flc_loc);
208
      if not ifstack:
209
        raise asmDef.AsmException('Unmatched ".ENDIF" in %s' % flc_loc);
210
      ifstack.pop();
211
    elif re.match(r'\s*\.IFN?DEF\b',body[-1]):
212
      a = re.findall(r'\s*(\.IFN?DEF)\s*(\S+)\b\s*(;.*)?$',body[-1]);
213
      if not a:
214
        raise asmDef.AsmException('Malformed .IFDEF or .IFNDEF in %s' % flc_loc);
215
      a = a[0];
216
      ifstack.append(ad.IsSymbol(a[1]));
217
      if a[0] == '.IFNDEF':
218
        ifstack[-1] ^= True;
219
    # Ignore bodies rejected by conditional compilation.
220
    elif ifstack and not ifstack[-1]:
221
      pass;
222
    # ".include" directives don't have an associated body
223
    elif re.match(r'\s*\.include\s',body[-1]):
224
      a = re.findall(r'\s*\.include\s+(\S+)(\s*|\s*;.*)$',body[-1]);
225
      if not a:
226
        raise asmDef.AsmException('Malformed .include directive in %s' % flc_loc);
227
      a = a[0];
228
      fbi.Include(a[0]);
229
    # Parse the body of all other directives and ensure that only one ".main"
230
    # and one ".interrupt" are defined.
231
    else:
232
      rawTokens = asmDef.RawTokens(ad,filename,startLine,body);
233
      if not rawTokens:
234
        continue;
235
      ad.CheckRawTokens(rawTokens);
236
      ad.FillRawTokens(rawTokens);
237
 
238
  #
239
  # Ensure a ".main" body was declared.
240
  #
241
 
242
  if not ad.Main():
243
    raise asmDef.AsmException('Required ".main" body not provided');
244
 
245
  #
246
  # Enforce consistency between the command-line "-i" flag and whether or not an
247
  # ".interrupt" body was declared.
248
  #
249
 
250
  if argList.i and not ad.Interrupt():
251
    raise asmDef.AsmException('Required ".interrupt" body not provided');
252
  if not argList.i and ad.Interrupt():
253
    raise asmDef.AsmException('".interrupt" body not allowed near %s' % ad.Interrupt()[0]['loc']);
254
 
255
  ################################################################################
256
  #
257
  # Stage 2:  Identify the required functions, compute their addresses, and set
258
  # the addresses for all "jump" and "call" macros.
259
  #
260
  ################################################################################
261
 
262
  ad.EvaluateMemoryTree();
263
  ad.EvaluateFunctionTree();
264
 
265
  ################################################################################
266
  #
267
  # Stage 3:  Emit the program
268
  #
269
  # Do the following:
270
  # - If interrupts are enabled, then set the first 4 instructions to be a "dis"
271
  #   and a ".jump" instruction to the ".interrupt" function.
272
  # - Write the instructions for the ".main" body.
273
  # - Loop through the ".function" list in the order in which they were defined
274
  #   and write their instructions.
275
  # - Print the memory and instruction usage statistics.
276
  #
277
  ################################################################################
278
 
279
  ad.EmitMemories(argList.o);
280
  ad.EmitProgram(argList.o);
281
  argList.o.close();
282
 
283
################################################################################
284
#
285
# Terminating except clause -- print fatal error message and indicate failure to
286
# the invoking program.
287
#
288
################################################################################
289
 
290
except asmDef.AsmException, msg:
291
  print >> sys.stderr, 'FATAL ERROR:  ' + str(msg);
292
  exit(1);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.