Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
/* linux/assembler.c */
32
 
33
/**********************************************************************
34
$Author: release $
35
$Date: 1998/01/17 15:55:52 $
36
$Revision: 1.1.1.1 $
37
$Log: assembler.c,v $
38
 * Revision 1.1.1.1  1998/01/17  15:55:52  release
39
 * First version to be checked into rolling release.
40
 *
41
 * Revision 1.10  1997/03/24  12:43:22  pwe
42
 * outn int->long
43
 *
44
 * Revision 1.9  1996/02/16  10:11:01  pwe
45
 * Linux/ELF struct result and PIC jump table
46
 *
47
 * Revision 1.8  1996/02/08  13:45:24  pwe
48
 * Linux elf v aout option
49
 *
50
 * Revision 1.7  1995/11/23  12:17:02  pwe
51
 * linux elf
52
 *
53
 * Revision 1.6  1995/10/13  15:20:07  pwe
54
 * solaris PIC and linux tcc
55
 *
56
 * Revision 1.5  1995/10/09  15:14:20  pwe
57
 * dynamic initialisation etc
58
 *
59
 * Revision 1.4  1995/04/12  13:22:04  pwe
60
 * end_tdf label added in case nothing but static strings
61
 *
62
 * Revision 1.3  1995/01/30  12:57:10  pwe
63
 * Ownership -> PWE, tidy banners
64
 *
65
 * Revision 1.2  1995/01/27  17:24:41  jmf
66
 * Unknown change?
67
 *
68
 * Revision 1.1  1994/11/08  16:27:43  jmf
69
 * Initial revision
70
 *
71
 * Revision 1.2  1994/07/13  07:51:05  jmf
72
 * Added Log
73
 *
74
**********************************************************************/
75
 
76
 
77
#include "config.h"
78
#include "common_types.h"
79
#include "out.h"
80
#include "expmacs.h"
81
#include "exp.h"
82
#include "localflags.h"
83
#include "shapemacs.h"
84
#include "operand.h"
85
#include "machine.h"
86
#include "flags.h"
87
#include "basicread.h"
88
#include "coder.h"
89
#include "assembler.h"
90
#include "instr.h"
91
#include "instr386.h"
92
#include "xalloc.h"
93
#include "install_fns.h"
94
#include <string.h>
95
 
96
 
97
 
98
/* PROCEDURES */
99
 
100
void dot_align
101
    PROTO_N ( (n) )
102
    PROTO_T ( int n )
103
{
104
  if (linux_elf) {
105
    outs(".align "); outn((long)n); outnl();
106
    return;
107
  }
108
  if (n == 1)
109
    return;
110
  outs(".align ");
111
  switch (n) {
112
    case 16:
113
      n = 4; break;
114
    case 8:
115
      n = 3; break;
116
    case 4:
117
      n = 2; break;
118
    default:
119
      n = 1; break;
120
  };
121
 
122
  outn((long)n); outnl();
123
  return;
124
}
125
 
126
 
127
void outbyte
128
    PROTO_Z ()
129
{
130
  outs(".byte ");
131
  return;
132
}
133
 
134
void outshort
135
    PROTO_Z ()
136
{
137
  outs(".value ");
138
  return;
139
}
140
 
141
void outlong
142
    PROTO_Z ()
143
{
144
  outs(".long ");
145
  return;
146
}
147
 
148
void align_label
149
    PROTO_N ( (f, jr) )
150
    PROTO_T ( int f X exp jr )
151
{
152
  if (linux_elf) {
153
    if (is80486 && !is80586 && ptno(jr) != last_jump_label) {
154
/* forward jump and continued into
155
      if (f==0)
156
        outs(".align 8");
157
*/
158
      if (f == 1)	/* repeat jump */
159
        outs(".align 4");
160
      if (f == 2)	/* preceded by a jmp or ret */
161
        outs(".align 16");
162
      outs("\n");
163
    };
164
    return;
165
  }
166
  else {
167
    if (is80486 && !is80586 && ptno(jr) != last_jump_label)  {
168
/* forward jump and continued into
169
      if (f==0)
170
        outs(".align 16,7,1");
171
*/
172
      if (f == 1)	/* repeat jump */
173
        outs(".align 3,0x90");
174
      if (f == 2)	/* preceded by a jmp or ret */
175
        outs(".align 4,0x90");
176
      if (f == 3)
177
        outs(".align 2,0x90");
178
      outs("\n");
179
    };
180
    if (is80586 && ptno(jr) != last_jump_label)  {
181
      if (f >= 1 && f <= 3)
182
        outs(".align 2,0x90\n");
183
    };
184
    return;
185
  }
186
}
187
 
188
void eval_postlude
189
    PROTO_N ( (s, c) )
190
    PROTO_T ( char * s X exp c )
191
{
192
  if (!linux_elf)
193
    return;
194
  outs(".size ");
195
  outs (s);
196
  outs (",");
197
  outn((long)(shape_size(sh(c))+7)/8);
198
  outnl();
199
  outs(".type ");
200
  outs (s);
201
  outs (",@object");
202
  outnl();
203
  return;
204
}
205
 
206
void out_readonly_section
207
    PROTO_Z ()
208
{
209
  if (linux_elf)
210
    outs (".section .rodata");
211
  else
212
    outs (".text");
213
  return;
214
}
215
 
216
void out_dot_comm
217
    PROTO_N ( (id, sha) )
218
    PROTO_T ( char * id X shape sha )
219
{
220
	outs (".comm ");
221
	outs (id);
222
	outs (",");
223
	outn ((long)((( shape_size(sha)/ 8) + 3) / 4) * 4);
224
 
225
	outnl ();
226
  return;
227
}
228
 
229
void out_dot_lcomm
230
    PROTO_N ( (id, sha) )
231
    PROTO_T ( char * id X shape sha )
232
{
233
	outs (".lcomm ");
234
	outs (id);
235
	outs (",");
236
	outn ((long)((( shape_size(sha)/ 8) + 3) / 4) * 4);
237
 
238
	outnl ();
239
  return;
240
}
241
 
242
void out_bss
243
    PROTO_N ( (id, sha) )
244
    PROTO_T ( char * id X shape sha )
245
{
246
	outs (".bss ");
247
	outs (id);
248
	outs (",");
249
	outn ((long)((( shape_size(sha)/ 8) + 3) / 4) * 4);
250
 
251
	outnl ();
252
  return;
253
}
254
 
255
static int pic_label;
256
 
257
void pic_prelude
258
    PROTO_Z ()
259
{
260
  int n = next_lab();
261
  pic_label = n;
262
  outs(" call "); outs(local_prefix); outn((long)n); outnl();
263
  outs(local_prefix); outn((long)n); outs(":"); outnl();
264
  outs(" popl %ebx"); outnl();
265
  outs(" addl $_GLOBAL_OFFSET_TABLE_+[.-"); outs(local_prefix); outn((long)n); outs("],%ebx");
266
    outnl();
267
  return;
268
}
269
 
270
void out_rename
271
    PROTO_N ( (oldid, newid) )
272
    PROTO_T ( char * oldid X char * newid )
273
{
274
  UNUSED(oldid); UNUSED(newid);
275
  return;
276
}
277
 
278
void out_switch_jump
279
    PROTO_N ( (tab, a, min) )
280
    PROTO_T ( int tab X where a X int min )
281
{
282
  if (PIC_code)  {
283
    if (min != 0) {
284
      sub (slongsh, mw(zeroe,min), a, reg0);
285
      a = reg0;
286
    }
287
    if (eq_where (a, reg0)) {
288
      outs (" movl ");
289
    }
290
    else {
291
      outs (" movl %ebx,%eax");
292
      outnl();
293
      outs (" subl ");
294
    }
295
    outs(local_prefix);
296
    outn((long)tab);
297
    outs("@GOTOFF(%ebx,");
298
    operand (32, a, 1, 0);
299
    outs(",4),%eax");
300
    outnl();
301
    if (eq_where (a, reg0)) {
302
      outs (" subl %ebx,%eax");
303
      outnl();
304
      outs (" negl %eax");
305
      outnl();
306
    }
307
    outs(" jmp *%eax");
308
    outnl();
309
    return;
310
  }
311
  else  {
312
    outs (" jmp *");
313
    outs(local_prefix);
314
    outn((long)tab);
315
    outs("-");
316
    outn((long)(4 * min));
317
    outs ("(,");
318
    operand (32, a, 1, 0);
319
    outs (",4)");
320
    outnl ();
321
    return;
322
  };
323
}
324
 
325
void out_switch_table
326
    PROTO_N ( (tab, min, max, v, absent) )
327
    PROTO_T ( int tab X int min X int max X int * v X int absent )
328
{
329
  int i;
330
 
331
  dot_align(4);
332
  outnl();
333
 
334
  outs(local_prefix);
335
  outn ((long)tab);
336
  outs (":");
337
  outnl ();
338
 
339
  for (i = min; i <= max; ++i) {
340
    outs (".long ");
341
    if (v[i - min] != -1)  {
342
      if (PIC_code) {
343
	outs(" _GLOBAL_OFFSET_TABLE_+[.-");
344
	outs(local_prefix);
345
	outn ((long)v[i - min]);
346
	outs("]");
347
      }
348
      else {
349
	outs(local_prefix);
350
	outn ((long)v[i - min]);
351
      }
352
    }
353
    else  {
354
      if (absent == -1)
355
        outn ((long)0);
356
      else {
357
	if (PIC_code) {
358
	  outs(" _GLOBAL_OFFSET_TABLE_+[.-");
359
	  outs(local_prefix);
360
	  outn ((long)absent);
361
	  outs("]");
362
	}
363
	else {
364
	  outs(local_prefix);
365
	  outn ((long)absent);
366
	}
367
      };
368
    };
369
    outnl ();
370
  };
371
  outnl();
372
  return;
373
}
374
 
375
void proc_size
376
    PROTO_N ( (s) )
377
    PROTO_T ( char * s )
378
{
379
  outs(".align 4");
380
  outnl();
381
  outs(".size ");
382
  outs(s);
383
  outs(", .-");
384
  outs(s);
385
  outnl();
386
  return;
387
}
388
 
389
void proc_type
390
    PROTO_N ( (s) )
391
    PROTO_T ( char * s )
392
{
393
  outs(".type ");
394
  outs(s);
395
  outs(",@function");
396
  outnl();
397
  return;
398
}
399
 
400
void outend
401
    PROTO_Z ()
402
{		/* close the output */
403
  int   st;
404
  outs(".text");
405
  outnl();
406
  dot_align(16);
407
  outnl();
408
  outs("___tdf_end:");
409
  outnl();
410
  st = fclose (fpout);
411
  if (st == EOF) {
412
    failer ("failed to close file");
413
    exit(EXIT_FAILURE);
414
  };
415
}
416
 
417
void outopenbr
418
    PROTO_Z ()
419
{
420
  return;
421
}
422
 
423
 
424
void outclosebr
425
    PROTO_Z ()
426
{
427
  return;
428
}
429
 
430
void outdivsym
431
    PROTO_Z ()
432
{
433
  outs("/");
434
  return;
435
}
436
 
437
void out_initialiser
438
    PROTO_N ( (id) )
439
    PROTO_T ( char* id )
440
{
441
  if (!linux_elf) {
442
    outs(".stabs \"___TDFI_LIST__\",22,0,0,");
443
    outs (id);
444
    outnl ();
445
    outnl ();
446
    return;
447
  }
448
  outs (".section .init\n");
449
  outs (" call ");
450
  outs (id);
451
  if (PIC_code)
452
    outs ("@PLT");
453
  outnl ();
454
  outnl ();
455
  return;
456
}
457
 
458
 
459
void out_main_prelude
460
    PROTO_Z ()		/* if (!linux_elf) */
461
{
462
  int nl1 = next_lab ();
463
  int nl2 = next_lab ();
464
  min_rfree |= 0x8;
465
  outs (" movl $___TDFI_LIST__+4, %ebx\n");
466
  outs (local_prefix);
467
  outn ((long)nl1);
468
  outs (":\n");
469
  outs (" movl (%ebx),%eax\n");
470
  outs (" cmpl $0,%eax\n");
471
  simple_branch ("je", nl2);
472
  outs (" call *%eax\n");
473
  outs (" addl $4,%ebx\n");
474
  simple_branch ("jmp", nl1);
475
  outs (local_prefix);
476
  outn ((long)nl2);
477
  outs (":\n");
478
  return;
479
}
480
 
481
void out_main_postlude
482
    PROTO_Z ()	/* if (!linux_elf) */
483
{
484
  char * sdummy = "Idummy";
485
  char * pdummy = (char *) xcalloc (((int)strlen(local_prefix) +
486
				(int)strlen(sdummy) + 1), sizeof (char));
487
  strcpy (pdummy, local_prefix);
488
  strcat (pdummy, sdummy);
489
  outs (".text\n");
490
  outs (pdummy);
491
  outs (":\n");
492
  outs (" ret\n");
493
  out_initialiser(pdummy);
494
  return;
495
}
496