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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [gas/] [config/] [tc-scarts_16.c] - Blame information for rev 13

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

Line No. Rev Author Line
1 6 jlechner
/* tc-scarts_16.c -- Assembler for the SCARTS_16 family.
2
   Copyright 2001, 2002, 2003, 2005, 2006, 2007 Free Software Foundation.
3
   Contributed by Martin Walter <mwalter@opencores.org>
4
 
5
   This file is part of GAS, the GNU Assembler.
6
 
7
   GAS is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
 
12
   GAS is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with GAS; see the file COPYING.  If not, write to
19
   the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20
   Boston, MA 02110-1301, USA.  */
21
 
22
#include "as.h"
23
#include "subsegs.h"
24
#include "symcat.h"
25
#include "opcodes/scarts_16-desc.h"
26
#include "opcodes/scarts_16-opc.h"
27
#include "cgen.h"
28
#include "libbfd.h"
29
 
30
const char comment_chars[]        = ";";
31
const char line_comment_chars[]   = "#";
32
const char line_separator_chars[] = "|";
33
const char EXP_CHARS[]            = "eE";
34
const char FLT_CHARS[]            = "dD";
35
 
36
const char scarts_16_comment_chars[] = ";#";
37
 
38
 
39
/* Target specific short options. */
40
#define SCARTS_16_SHORTOPTS ""
41
const char *md_shortopts = SCARTS_16_SHORTOPTS;
42
 
43
/* Target specific long options. */
44
struct option md_longopts[] =
45
{
46
  {NULL, no_argument, NULL, 0}
47
};
48
 
49
size_t md_longopts_size = sizeof(md_longopts);
50
 
51
/* Set the default machine. */
52
#define DEFAULT_MACHINE bfd_mach_scarts_16
53
unsigned long scarts_16_mach = DEFAULT_MACHINE;
54
 
55
/* Target specific pseudo-ops. */
56
const pseudo_typeS md_pseudo_table[] =
57
{
58
  {NULL,  NULL, 0}
59
};
60
 
61
 
62
/* GAS will call md_parse_option whenever getopt returns an unrecognized code,
63
   presumably indicating a special code value which appears in md_longopts.
64
   This function should return non-zero if it handled the option and zero
65
   otherwise. There is no need to print a message about an option not being
66
   recognized. This will be handled by the generic code. */
67
int
68
md_parse_option(int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
69
{
70
  return 0;
71
}
72
 
73
/* GAS will call md_show_usage when a usage message is printed; it should print
74
   a description of the machine specific options. */
75
void
76
md_show_usage(FILE * stream ATTRIBUTE_UNUSED)
77
{
78
}
79
 
80
/* GAS will call this function at the start of the assembly, after the command
81
   line arguments have been parsed and all the machine independent
82
   initializations have been completed. */
83
void
84
md_begin(void)
85
{
86
  /* Set the machine number and endianness.  */
87
  gas_cgen_cpu_desc = scarts_16_cgen_cpu_open(CGEN_CPU_OPEN_MACHS, scarts_16_mach, CGEN_CPU_OPEN_ENDIAN, (target_big_endian ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE), CGEN_CPU_OPEN_END);
88
 
89
  scarts_16_cgen_init_asm(gas_cgen_cpu_desc);
90
 
91
  /* This is a callback from cgen to gas to parse operands.  */
92
  cgen_set_parse_operand_fn(gas_cgen_cpu_desc, gas_cgen_parse_operand);
93
 
94
  /* Set the machine type.  */
95
  bfd_default_set_arch_mach(stdoutput, bfd_arch_scarts_16, scarts_16_mach);
96
}
97
 
98
/* GAS will call this function for each input line which does not contain a
99
   pseudoop. The argument is a null terminated string. The function should
100
   assemble the string as an instruction with operands. */
101
void
102
md_assemble(char *str)
103
{
104
  const CGEN_INSN *insn;
105
  char *errmsg;
106
  CGEN_FIELDS fields;
107
 
108
#if CGEN_INT_INSN_P
109
  CGEN_INSN_INT buffer[CGEN_MAX_INSN_SIZE / sizeof(CGEN_INSN_INT)];
110
#else
111
  unsigned char buffer[CGEN_MAX_INSN_SIZE];
112
#endif
113
 
114
  gas_cgen_init_parse();
115
 
116
  insn = scarts_16_cgen_assemble_insn(gas_cgen_cpu_desc, str, &fields, buffer, &errmsg);
117
  if (!insn)
118
  {
119
    as_bad(errmsg);
120
    return;
121
  }
122
 
123
  /* MWA: Instead of the instruction size, CGEN_FIELDS_BITSIZE(&fields)
124
   * erroneously delivers the value of the instruction and is therefore
125
   * replaced by the the proper CGEN_INSN_BITSIZE(insn). */
126
  gas_cgen_finish_insn(insn, buffer, CGEN_INSN_BITSIZE(insn), 0, NULL);
127
}
128
 
129
/* GAS will call this function when a symbol table lookup fails, before it
130
   creates a new symbol. Typically this would be used to supply symbols whose
131
   name or value changes dynamically, possibly in a context sensitive way.
132
   Predefined symbols with fixed values, such as register names or condition
133
   codes, are typically entered directly into the symbol table when md_begin
134
   is called. */
135
symbolS *
136
md_undefined_symbol(char * name ATTRIBUTE_UNUSED)
137
{
138
  return 0;
139
}
140
 
141
/* GAS will call this function with one argument, an expressionS pointer, for
142
   any expression that can not be recognized. When the function is called,
143
   input_line_pointer will point to the start of the expression. */
144
void
145
md_operand(expressionS *exp)
146
{
147
  if (*input_line_pointer == ';' || *input_line_pointer == '#')
148
  {
149
    input_line_pointer++;
150
    expression(exp);
151
  }
152
}
153
 
154
/* This function is called to convert an ASCII string into a floating point
155
   value in format used by the CPU. It takes three arguments. The first is type
156
   which is a byte describing the type of floating point number to be created.
157
   Possible values are ’f’ or ’s’ for single precision, ’d’ or ’r’ for double
158
   precision and ’x’ or ’p’ for extended precision. Either lower or upper case
159
   versions of these letters can be used.
160
 
161
   The second parameter is litP which is a pointer to a byte array where the
162
   converted value should be stored. The third argument is sizeP, which is a
163
   pointer to a integer that should be filled in with the number of LITTLENUMs
164
   emitted into the byte array. (LITTLENUM is defined in gas/bignum.h). The
165
   function should return NULL upon success or an error string upon failure. */
166
 
167
/* Equal to MAX_PRECISION in atof-ieee.c. */
168
#define MAX_LITTLENUMS 6
169
 
170
char *
171
md_atof (int type, char *litP, int *sizeP)
172
{
173
  char *t;
174
  int i, prec;
175
  LITTLENUM_TYPE words[MAX_LITTLENUMS];
176
 
177
  switch (type)
178
  {
179
    case 'f':
180
    case 'F':
181
    case 's':
182
    case 'S':
183
      prec = 2;
184
      break;
185
 
186
    case 'd':
187
    case 'D':
188
    case 'r':
189
    case 'R':
190
      prec = 4;
191
      break;
192
 
193
   /* FIXME: Some targets allow other format chars for bigger sizes here. */
194
 
195
    default:
196
      * sizeP = 0;
197
      return _("Bad call to md_atof()");
198
  }
199
 
200
  t = atof_ieee(input_line_pointer, type, words);
201
  if (t)
202
    input_line_pointer = t;
203
 
204
  *sizeP = prec * sizeof(LITTLENUM_TYPE);
205
 
206
  for (i = 0; i < prec; i++)
207
  {
208
    md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
209
    litP += sizeof (LITTLENUM_TYPE);
210
  }
211
 
212
  return 0;
213
}
214
 
215
int
216
md_estimate_size_before_relax(register fragS *fragP ATTRIBUTE_UNUSED, register segT segment_type ATTRIBUTE_UNUSED)
217
{
218
  printf(_("Bad call to md_estimate_size_before_relax\n"));
219
  abort();
220
}
221
 
222
void
223
md_convert_frag(bfd *abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED, fragS *fragP ATTRIBUTE_UNUSED)
224
{
225
}
226
 
227
long
228
md_pcrel_from_section(fixS *fixP, segT sec)
229
{
230
  if (fixP->fx_addsy != (symbolS *) NULL && (! S_IS_DEFINED (fixP->fx_addsy) || S_GET_SEGMENT (fixP->fx_addsy) != sec))
231
    /* The symbol is undefined (or is defined but not in this section).
232
       Let the linker figure it out. */
233
    return 0;
234
 
235
  return (fixP->fx_frag->fr_address + fixP->fx_where);
236
}
237
 
238
valueT
239
md_section_align(segT segment, valueT size)
240
{
241
  int align = bfd_get_section_alignment(stdoutput, segment);
242
  return ((size + (1 << align) - 1) & (-1 << align));
243
}
244
 
245
/* GAS will call this for each fixup.
246
   It should store the correct value in the object file.  */
247
 
248
void
249
scarts_16_md_apply_fix(fixS *fixP, valueT * valP, segT seg)
250
{
251
  long value;
252
  value = *valP;
253
 
254
  /* It is assumed that the program counter gets incremented after
255
   * an instruction fetch. In this case, a PC-relative relocation
256
   * value would need to be adjusted by the incrementation value. */
257
  /*
258
  if (fixP->fx_pcrel == 1)
259
    value -= 2;
260
  */
261
 
262
  gas_cgen_md_apply_fix(fixP, (valueT *)&value, seg);
263
}
264
 
265
int
266
scarts_16_force_relocation (fixP)
267
  fixS *fixP;
268
{
269
  int type;
270
  type = fixP->fx_r_type < BFD_RELOC_UNUSED ? (int) fixP->fx_r_type : fixP->fx_cgen.opinfo;
271
 
272
  switch (type)
273
  {
274
    case BFD_RELOC_SCARTS_16_PCREL_10:
275
      return 1;
276
    default:
277
      break;
278
  }
279
 
280
  return generic_force_reloc(fixP);
281
}
282
 
283
/* Return the bfd reloc type for OPERAND of INSN at fixup fixP.
284
   Returns BFD_RELOC_NONE if no reloc type can be found. */
285
 
286
bfd_reloc_code_real_type
287
md_cgen_lookup_reloc(const CGEN_INSN *insn ATTRIBUTE_UNUSED, const CGEN_OPERAND *operand, fixS *fixP)
288
{
289
  bfd_reloc_code_real_type type;
290
  type = BFD_RELOC_NONE;
291
 
292
  switch (operand->type)
293
  {
294
    case SCARTS_16_OPERAND_SIMM8:
295
      fixP->fx_pcrel = 0;
296
 
297
      if (fixP->fx_cgen.opinfo != 0)
298
        type = fixP->fx_cgen.opinfo;
299
 
300
      break;
301
 
302
    case SCARTS_16_OPERAND_UIMM8:
303
      fixP->fx_pcrel = 0;
304
 
305
      if (fixP->fx_cgen.opinfo != 0)
306
        type = fixP->fx_cgen.opinfo;
307
 
308
      break;
309
 
310
    case SCARTS_16_OPERAND_SADDR10_PCREL:
311
      fixP->fx_pcrel = 1;
312
      type = BFD_RELOC_SCARTS_16_PCREL_10;
313
      break;
314
 
315
    default:
316
      break;
317
  }
318
 
319
  return type;
320
}

powered by: WebSVN 2.1.0

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