Subversion Repositories tendra.SVN

Rev

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

Rev Author Line No. Line
2 7u83 1
/*
7 7u83 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
/*
2 7u83 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
 
7 7u83 130
void
131
dot_align(int n)
2 7u83 132
{
133
  if (linux_elf) {
7 7u83 134
    outs(".align ");
135
    outn((long)n);
136
    outnl();
2 7u83 137
    return;
138
  }
7 7u83 139
  if (n == 1) {
2 7u83 140
    return;
7 7u83 141
  }
2 7u83 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
 
7 7u83 154
  outn((long)n);
155
  outnl();
2 7u83 156
  return;
157
}
158
 
159
 
7 7u83 160
void
161
outbyte(void)
2 7u83 162
{
163
  outs(".byte ");
164
  return;
165
}
166
 
7 7u83 167
void
168
outshort(void)
2 7u83 169
{
170
  outs(".value ");
171
  return;
172
}
173
 
7 7u83 174
void
175
outlong(void)
2 7u83 176
{
177
  outs(".long ");
178
  return;
179
}
180
 
7 7u83 181
void
182
align_label(int f, exp jr)
2 7u83 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
*/
7 7u83 190
      if (f == 1) {	/* repeat jump */
2 7u83 191
        outs(".align 4");
7 7u83 192
      }
193
      if (f == 2) {	/* preceded by a jmp or ret */
2 7u83 194
        outs(".align 16");
7 7u83 195
      }
2 7u83 196
      outs("\n");
7 7u83 197
    }
2 7u83 198
    return;
7 7u83 199
  } else {
200
    if (is80486 && !is80586 && ptno(jr)!= last_jump_label) {
2 7u83 201
/* forward jump and continued into
202
      if (f==0)
203
        outs(".align 16,7,1");
204
*/
7 7u83 205
      if (f == 1) {	/* repeat jump */
2 7u83 206
        outs(".align 3,0x90");
7 7u83 207
      }
208
      if (f == 2) {	/* preceded by a jmp or ret */
2 7u83 209
        outs(".align 4,0x90");
7 7u83 210
      }
211
      if (f == 3) {
2 7u83 212
        outs(".align 2,0x90");
7 7u83 213
      }
2 7u83 214
      outs("\n");
7 7u83 215
    }
216
    if (is80586 && ptno(jr)!= last_jump_label) {
217
      if (f >= 1 && f <= 3) {
2 7u83 218
        outs(".align 2,0x90\n");
7 7u83 219
      }
220
    }
2 7u83 221
    return;
222
  }
223
}
224
 
7 7u83 225
void
226
eval_postlude(char *s, exp c)
2 7u83 227
{
7 7u83 228
  if (!linux_elf) {
2 7u83 229
    return;
7 7u83 230
  }
2 7u83 231
  outs(".size ");
7 7u83 232
  outs(s);
233
  outs(",");
234
  outn((long)(shape_size(sh(c)) + 7) / 8);
2 7u83 235
  outnl();
236
  outs(".type ");
7 7u83 237
  outs(s);
238
  outs(",@object");
2 7u83 239
  outnl();
240
  return;
241
}
242
 
7 7u83 243
void
244
out_readonly_section(void)
2 7u83 245
{
7 7u83 246
  if (linux_elf) {
247
    outs(".section .rodata");
248
  } else {
249
    outs(".text");
250
  }
2 7u83 251
  return;
252
}
253
 
7 7u83 254
void
255
out_dot_comm(char *id, shape sha)
2 7u83 256
{
7 7u83 257
	outs(".comm ");
258
	outs(id);
259
	outs(",");
260
	outn((long)(((shape_size(sha) / 8) + 3) / 4) * 4);
2 7u83 261
 
7 7u83 262
	outnl();
2 7u83 263
  return;
264
}
265
 
7 7u83 266
void
267
out_dot_lcomm(char *id, shape sha)
2 7u83 268
{
7 7u83 269
	outs(".lcomm ");
270
	outs(id);
271
	outs(",");
272
	outn((long)(((shape_size(sha) / 8) + 3) / 4) * 4);
2 7u83 273
 
7 7u83 274
	outnl();
2 7u83 275
  return;
276
}
277
 
7 7u83 278
void
279
out_bss(char *id, shape sha)
2 7u83 280
{
7 7u83 281
	outs(".bss ");
282
	outs(id);
283
	outs(",");
284
	outn((long)(((shape_size(sha) / 8) + 3) / 4) * 4);
2 7u83 285
 
7 7u83 286
	outnl();
2 7u83 287
  return;
288
}
289
 
290
static int pic_label;
291
 
7 7u83 292
void
293
pic_prelude(void)
2 7u83 294
{
295
  int n = next_lab();
296
  pic_label = n;
7 7u83 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();
2 7u83 312
  return;
313
}
314
 
7 7u83 315
void
316
out_rename(char *oldid, char *newid)
2 7u83 317
{
7 7u83 318
  UNUSED(oldid);
319
  UNUSED(newid);
2 7u83 320
  return;
321
}
322
 
7 7u83 323
void
324
out_switch_jump(int tab, where a, int min)
2 7u83 325
{
7 7u83 326
  if (PIC_code) {
2 7u83 327
    if (min != 0) {
7 7u83 328
      sub(slongsh, mw(zeroe,min), a, reg0);
2 7u83 329
      a = reg0;
330
    }
7 7u83 331
    if (eq_where(a, reg0)) {
332
      outs(" movl ");
333
    } else {
334
      outs(" movl %ebx,%eax");
2 7u83 335
      outnl();
7 7u83 336
      outs(" subl ");
2 7u83 337
    }
338
    outs(local_prefix);
339
    outn((long)tab);
340
    outs("@GOTOFF(%ebx,");
7 7u83 341
    operand(32, a, 1, 0);
2 7u83 342
    outs(",4),%eax");
343
    outnl();
7 7u83 344
    if (eq_where(a, reg0)) {
345
      outs(" subl %ebx,%eax");
2 7u83 346
      outnl();
7 7u83 347
      outs(" negl %eax");
2 7u83 348
      outnl();
349
    }
350
    outs(" jmp *%eax");
351
    outnl();
352
    return;
7 7u83 353
  } else  {
354
    outs(" jmp *");
2 7u83 355
    outs(local_prefix);
356
    outn((long)tab);
357
    outs("-");
358
    outn((long)(4 * min));
7 7u83 359
    outs("(,");
360
    operand(32, a, 1, 0);
361
    outs(",4)");
362
    outnl();
2 7u83 363
    return;
364
  };
365
}
366
 
7 7u83 367
void
368
out_switch_table(int tab, int min, int max, int *v, int absent)
2 7u83 369
{
370
  int i;
371
 
372
  dot_align(4);
373
  outnl();
374
 
375
  outs(local_prefix);
7 7u83 376
  outn((long)tab);
377
  outs(":");
378
  outnl();
2 7u83 379
 
380
  for (i = min; i <= max; ++i) {
7 7u83 381
    outs(".long ");
382
    if (v[i - min]!= -1) {
2 7u83 383
      if (PIC_code) {
7 7u83 384
	outs(" _GLOBAL_OFFSET_TABLE_+ [.-");
2 7u83 385
	outs(local_prefix);
7 7u83 386
	outn((long)v[i - min]);
2 7u83 387
	outs("]");
7 7u83 388
      } else {
2 7u83 389
	outs(local_prefix);
7 7u83 390
	outn((long)v[i - min]);
2 7u83 391
      }
7 7u83 392
    } else {
393
      if (absent == -1) {
394
        outn((long)0);
395
      } else {
2 7u83 396
	if (PIC_code) {
7 7u83 397
	  outs(" _GLOBAL_OFFSET_TABLE_+ [.-");
2 7u83 398
	  outs(local_prefix);
7 7u83 399
	  outn((long)absent);
2 7u83 400
	  outs("]");
7 7u83 401
	} else {
2 7u83 402
	  outs(local_prefix);
7 7u83 403
	  outn((long)absent);
2 7u83 404
	}
7 7u83 405
      }
406
    }
407
    outnl();
408
  }
2 7u83 409
  outnl();
410
  return;
411
}
412
 
7 7u83 413
void
414
proc_size(char *s)
2 7u83 415
{
416
  outs(".align 4");
417
  outnl();
418
  outs(".size ");
419
  outs(s);
420
  outs(", .-");
421
  outs(s);
422
  outnl();
423
  return;
424
}
425
 
7 7u83 426
void
427
proc_type(char *s)
2 7u83 428
{
429
  outs(".type ");
430
  outs(s);
431
  outs(",@function");
432
  outnl();
433
  return;
434
}
435
 
7 7u83 436
void
437
outend(void)
2 7u83 438
{		/* close the output */
7 7u83 439
  int st;
2 7u83 440
  outs(".text");
441
  outnl();
442
  dot_align(16);
443
  outnl();
444
  outs("___tdf_end:");
445
  outnl();
7 7u83 446
  st = fclose(fpout);
2 7u83 447
  if (st == EOF) {
7 7u83 448
    failer("failed to close file");
2 7u83 449
    exit(EXIT_FAILURE);
7 7u83 450
  }
2 7u83 451
}
452
 
7 7u83 453
void
454
outopenbr(void)
2 7u83 455
{
456
  return;
457
}
458
 
459
 
7 7u83 460
void
461
outclosebr(void)
2 7u83 462
{
463
  return;
464
}
465
 
7 7u83 466
void
467
outdivsym(void)
2 7u83 468
{
469
  outs("/");
470
  return;
471
}
472
 
7 7u83 473
void
474
out_initialiser(char *id)
2 7u83 475
{
476
  if (!linux_elf) {
477
    outs(".stabs \"___TDFI_LIST__\",22,0,0,");
7 7u83 478
    outs(id);
479
    outnl();
480
    outnl();
2 7u83 481
    return;
482
  }
7 7u83 483
  outs(".section .init\n");
484
  outs(" call ");
485
  outs(id);
486
  if (PIC_code) {
487
    outs("@PLT");
488
  }
489
  outnl();
490
  outnl();
2 7u83 491
  return;
492
}
493
 
494
 
7 7u83 495
void
496
out_main_prelude(void)
2 7u83 497
{
7 7u83 498
  /* if (!linux_elf) */
499
  int nl1 = next_lab();
500
  int nl2 = next_lab();
2 7u83 501
  min_rfree |= 0x8;
7 7u83 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");
2 7u83 515
  return;
516
}
517
 
7 7u83 518
void
519
out_main_postlude(void)
2 7u83 520
{
7 7u83 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");
2 7u83 531
  out_initialiser(pdummy);
532
  return;
533
}
534