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

Subversion Repositories marca

[/] [marca/] [tags/] [INITIAL/] [spar/] [checks.c] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jeunes2
/* This file is part of the assembler "spar" for marca.
2
   Copyright (C) 2007 Wolfgang Puffitsch
3
 
4
   This program is free software; you can redistribute it and/or modify it
5
   under the terms of the GNU Library General Public License as published
6
   by the Free Software Foundation; either version 2, or (at your option)
7
   any later version.
8
 
9
   This program is distributed in the hope that it will be useful,
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
   Library General Public License for more details.
13
 
14
   You should have received a copy of the GNU Library General Public
15
   License along with this program; if not, write to the Free Software
16
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA */
17
 
18
#include <stdint.h>
19
#include <stdio.h>
20
 
21
#include "spar.h"
22
#include "ui.h"
23
#include "checks.h"
24
#include "code.h"
25
#include "exprs.h"
26
#include "optab.h"
27
#include "segtab.h"
28
#include "symtab.h"
29
 
30
int check_premature(void)
31
{
32
  if (args_to_match > 0)
33
    {
34
      fprintf(stderr, "not enough valid items in line %lu\n", line_count);
35
      error_count++;
36
      return 1;
37
    }
38
  return 0;
39
}
40
 
41
int check_arg_count(void)
42
{
43
  if (args_to_match == 0)
44
    {
45
      fprintf(stderr, "too many items in line %lu\n", line_count);
46
      error_count++;
47
      return 1;
48
    }
49
  else if (args_to_match == -1)
50
    {
51
      fprintf(stderr, "no valid mnemonic in line %lu\n", line_count);
52
      args_to_match = -2;
53
      error_count++;
54
      return 1;
55
    }
56
  else if ((args_to_match & 1) == 0)
57
    {
58
      fprintf(stderr, "missing colon in line %lu\n", line_count);
59
      error_count++;
60
      return 1;
61
    }
62
 
63
  return 0;
64
}
65
 
66
int check_org_advances(struct seg *seg, uint32_t org)
67
{
68
  if (seg->pos > org)
69
    {
70
      fprintf(stderr, "trying to move .org backwards in line %lu\n", line_count);
71
      error_count++;
72
      return 1;
73
    }
74
  return 0;
75
}
76
 
77
int check_colon_ok(void)
78
{
79
 if ((args_to_match & 1) != 0)
80
    {
81
      fprintf(stderr, "superfluous colon in line %lu\n", line_count);
82
      error_count++;
83
      return 1;
84
    }
85
 
86
  return 0;
87
}
88
 
89
int check_arg_type(struct seg* seg, uint32_t pos, uint8_t index, char type)
90
{
91
  if (((type == 'r')
92
       && (get_arg_type(seg, pos, index) != 'r'))
93
      || ((type == 'n')
94
          && (get_arg_type(seg, pos, index) != 'n')
95
          && (get_arg_type(seg, pos, index) != 'a')))
96
 
97
    {
98
      fprintf(stderr, "wrong argtype `%c' in line %lu\n", type, line_count);
99
      error_count++;
100
      return 1;
101
    }
102
  return 0;
103
}
104
 
105
int check_sym_dup(const char *s)
106
{
107
  if (get_sym(s) != NULL)
108
    {
109
      fprintf(stderr, "duplicate symbol `%s' in line %lu\n", s, line_count);
110
      error_count++;
111
      return 1;
112
    }
113
  return 0;
114
}
115
 
116
int check_code_size(void)
117
{
118
  if (get_seg(SEG_TEXT)->pos > codesize)
119
    {
120
      fprintf(stderr,
121
              "code (%lu instrucions) is too large for instruction ROM (%lu instructions)\n",
122
              get_seg(SEG_TEXT)->pos, codesize);
123
      error_count++;
124
      return 1;
125
    }
126
  return 0;
127
}
128
 
129
int check_data_size(void)
130
{
131
  if (output_mode == MODE_DOWNLOAD
132
      && get_seg(SEG_DATA)->pos > 0)
133
    {
134
      fprintf(stderr,
135
              "initialized data (%lu words) not supported for download format\n",
136
              get_seg(SEG_DATA)->pos, romsize);
137
      error_count++;
138
      return 1;
139
    }
140
 
141
  if (get_seg(SEG_DATA)->pos > romsize)
142
    {
143
      fprintf(stderr,
144
              "initialized data (%lu words) is too large for data ROM (%lu words)\n",
145
              get_seg(SEG_DATA)->pos, romsize);
146
      error_count++;
147
      return 1;
148
    }
149
 
150
  if ((get_seg(SEG_DATA)->pos+get_seg(SEG_BSS)->pos) > datasize)
151
    {
152
      fprintf(stderr,
153
              "data (%lu words) is too large for RAM (%lu words)\n",
154
              (get_seg(SEG_DATA)->pos+get_seg(SEG_BSS)->pos), datasize);
155
      error_count++;
156
      return 1;
157
    }
158
  return 0;
159
}
160
 
161
int check_mnemonic(struct seg* seg, uint32_t pos)
162
{
163
  if (0)
164
    {
165
      fprintf(stderr, "mnemonic reserved, but not supported\n");
166
      error_count++;
167
      return 1;
168
    }
169
  return 0;
170
}
171
 
172
int check_ranges(struct seg* seg, uint32_t pos)
173
{
174
  uint8_t count = get_arg_count(seg, pos);
175
  uint8_t index;
176
  int retval = 0;
177
 
178
  for (index = 0; index < count; index++)
179
    {
180
      switch (get_arg_type(seg, pos, index))
181
        {
182
        case 'r':
183
          if ((get_regnum(seg, pos, index) < get_arg_min(seg, pos, index))
184
              || (get_regnum(seg, pos, index) > get_arg_max(seg, pos, index)))
185
            {
186
              fprintf(stderr, "invalid register: r%d\n", get_regnum(seg, pos, index));
187
              error_count++;
188
              retval = 1;
189
            }
190
          break;
191
        case 'n':
192
          if (get_expr(seg, pos, index) == NULL)
193
            {
194
              fprintf(stderr, "missing expression, probably confused by prior errors\n");
195
              error_count++;
196
              retval = 1;
197
            }
198
          else if ((expr_evaluate(get_expr(seg, pos, index)) < get_arg_min(seg, pos, index))
199
              || (expr_evaluate(get_expr(seg, pos, index)) > get_arg_max(seg, pos, index)))
200
            {
201
              fprintf(stderr, "number out of range [%ld..%ld]: %lld\n",
202
                      get_arg_min(seg, pos, index), get_arg_max(seg, pos, index),
203
                      expr_evaluate(get_expr(seg, pos, index)));
204
              error_count++;
205
              retval = 1;
206
            }
207
          break;
208
        case 'a':
209
          if ((expr_evaluate(get_expr(seg, pos, index)) < get_arg_min(seg, pos, index))
210
              || (expr_evaluate(get_expr(seg, pos, index)) > get_arg_max(seg, pos, index)))
211
            {
212
              fprintf(stderr, "relative address out of range [%ld..%ld]: %lld\n",
213
                      get_arg_min(seg, pos, index), get_arg_max(seg, pos, index),
214
                      expr_evaluate(get_expr(seg, pos, index)));
215
              error_count++;
216
              retval = 1;
217
            }
218
          break;
219
        default:
220
          fprintf(stderr, "invalid operand constraint: %c\n",
221
                  get_arg_type(seg, pos, index));
222
          error_count++;
223
          retval = 1;
224
        }
225
    }
226
 
227
  return retval;
228
}
229
 

powered by: WebSVN 2.1.0

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