Subversion Repositories tendra.SVN

Rev

Rev 6 | Details | Compare with Previous | Last modification | View Log | RSS feed

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