📄 out68k_q.c
字号:
/* * C compiler * ========== * * Copyright 1993, David J. Walker. * All commercial rights reserved. * * This source module may be redistributed as long there is no * commercial interest. The compiler must not be redistributed * without its full sources. This notice must stay intact. * * History: * * 1993 First version. Modelled on the ACK version. *//*****************************************************************************/#include "config.h"#ifdef MC680X0#ifdef TARGET_QMAC#define OUT_MODULE#include "chdr.h"#include "expr.h"#include "cglbdec.h"#include "proto.h"#include "gen68k.h"#include "outproto.h"#include "version.h"/********************************************************** Type Definitions */enum e_gt{ bytegen, wordgen, longgen, longlonggen, stringgen, nogen};enum e_sg{ noseg, codeseg, dataseg, bssseg, romseg};/*********************************************** Static Function Definitions */static void putop P_ ((OPCODE));static void putconst P_ ((const EXPR *, ILEN));static void putlen P_ ((ILEN));static void putamode P_ ((const ADDRESS *, ILEN));static void put_mask P_ ((REGMASK));static void put_rmask P_ ((REGMASK));static void put_smask P_ ((REGMASK));static void putreg P_ ((REG));static void put_header P_ ((enum e_gt, SIZE));static void seg P_ ((enum e_sg, const char *, SIZE));static void put_bseg P_ ((SIZE));static void nl P_ ((void));static void put_align P_ ((SIZE));/*********************************************** Global Function Definitions */PRIVATE void put_name P_ ((SYM *));PRIVATE void put_dword P_ ((UVAL));PRIVATE void put_cseg P_ ((SIZE));PRIVATE void put_dseg P_ ((SIZE));PRIVATE void put_kseg P_ ((SIZE));PRIVATE void put_rseg P_ ((SIZE));PRIVATE void put_label P_ ((LABEL));PRIVATE void put_reference P_ ((SYM *));PRIVATE void put_byte P_ ((UVAL));/********************************************************** Static Variables *//* variable initialization */static enum e_gt gentype = nogen;static enum e_sg curseg = noseg;static int outcol = 0;static SIZE align_type = 0L;static const char *prefix = "I_";static const char *comment = ";";static const char *opl[] = { "MOVE", /* op_move */ "MOVEQ", /* op_moveq */ "MOVEA", /* op_movea */ "ADD", /* op_add */ "ADDI", /* op_addi */ "ADDQ", /* op_addq */ "ADDA", /* op_adda */ "ADDX", /* op_addx */ "SUB", /* op_sub */ "SUBI", /* op_subi */ "SUBQ", /* op_subq */ "SUBA", /* op_suba */ "SUBX", /* op_subx */ "MULS", /* op_muls */ "MULU", /* op_mulu */ "DIVS", /* op_divs */ "DIVU", /* op_divu */ "AND", /* op_and */ "OR", /* op_or */ "EOR", /* op_eor */ "ASL", /* op_asl */ "LSR", /* op_lsr */ "JMP", /* op_jmp */ "JSR", /* op_jsr */ "BSR", /* op_bsr */ "MOVEM", /* op_movem */ "RTS", /* op_rts */ "RTE", /* op_rte */ "BRA", /* op_bra */ "BEQ", /* op_beq */ "BNE", /* op_bne */ "BLT", /* op_blt */ "BLE", /* op_ble */ "BGT", /* op_bgt */ "BGE", /* op_bge */ "BHI", /* op_bhi */ "BCC", /* op_bhs */ "BCS", /* op_blo */ "BLS", /* op_bls */ "TST", /* op_tst */ "EXT", /* op_ext */ "EXTB", /* op_extb */ "LEA", /* op_lea */ "SWAP", /* op_swap */ "NEG", /* op_neg */ "NEGX", /* op_negx */ "NOT", /* op_not */ "CMP", /* op_cmp */ "CMPA", /* op_cmpa */ "CLR", /* op_clr */ "LINK", /* op_link */ "UNLK", /* op_unlk */ "PEA", /* op_pea */ "CMPI", /* op_cmpi */ "DBRA", /* op_dbra */ "ASR", /* op_asr */ "ROL", /* op_rol */ "ROR", /* op_ror */ "ROXL", /* op_roxl */ "ROXR", /* op_roxr */ "SEQ", /* op_seq */ "SNE", /* op_sne */ "SLT", /* op_slt */ "SLE", /* op_sle */ "SGT", /* op_sgt */ "SGE", /* op_sge */ "SHI", /* op_shi */ "SCC", /* op_shs */ "SCS", /* op_slo */ "SLS", /* op_sls */ "NOP", /* op_nop */
"TRAP", /* op_trap */#ifdef FLOAT_IEEE "FADD", /* op_fadd */ "FSUB", /* op_fsub */ "FDIV", /* op_fdiv */ "FMUL", /* op_fmul */ "FCMP", /* op_fcmp */ "FMOVE", /* op_fmove */ "FMOVEM", /* op_fmovem */#endif /* FLOAT_IEEE */#ifdef ASM "", /* op_asm */#endif /* ASM */ "COMMENT", /* op_line */ (char *) NULL, /* op_label */};/*****************************************************************************/static void putop P1 (OPCODE, op){ if (op >= OP_MIN && op <= OP_MAX && opl[op] != (char *) 0) { oprintf ("\t%s", opl[op]); } else { FATAL ((__FILE__, "putop", "illegal opcode %d", op)); }}/* * put a constant to the output file. */static void putconst P2 (const EXPR *, ep, ILEN, len){ switch (ep->nodetype) { case en_autocon: case en_icon: if (len == IL8) {#ifdef LONGLONG oprintf ("%ld", (long) ((UVAL) ep->v.i >> 32));#else if (is_signed_type (ep->etp) && ep->v.i < 0) { oprintf ("-1"); } else { oprintf ("0"); } #endif /* LONGLONG */ } else { oprintf ("%ld", (long) ep->v.i); } break;#ifndef FLOAT_BOOTSTRAP#ifdef FLOAT_MFFP case en_fcon: oprintf ("$%lX", genffp (ep->v.f)); break;#endif /* FLOAT_MFFP */#endif /* FLOAT_BOOTSTRAP */ case en_labcon: oprintf ("%s%u", prefix, (unsigned) ep->v.l); break; case en_nacon: if (len == IL8) { oprintf ("0"); } else { oprintf ("%s", outlate (ep->v.str)); } break; case en_sym: oprintf ("%s", outlate (nameof (ep->v.sp))); break; case en_add: putconst (ep->v.p[0], len); oprintf ("+"); putconst (ep->v.p[1], len); break; case en_sub: putconst (ep->v.p[0], len); oprintf ("-"); putconst (ep->v.p[1], len); break; case en_uminus: oprintf ("-"); /*lint -fallthrough */ case en_cast: putconst (ep->v.p[0], len); break; case en_str: oprintf ("%s", ep->v.str); break; default: FATAL ( (__FILE__, "putconst", "illegal constant node %d", ep->nodetype)); break; }}/* * append the length field to an instruction. */static void putlen P1 (ILEN, l){ switch (l) { case IL0: break; case IL1: oprintf (".B"); break; case IL2: oprintf (".W"); break; case IL4: oprintf (".L"); break; case (ILEN) (IL4 + 1): oprintf (".S"); break; case (ILEN) (IL8 + 1): oprintf (".D"); break; case (ILEN) (IL12 + 1): oprintf (".X"); break; default: FATAL ((__FILE__, "putlen", "illegal length field %d", (int) l)); break; }}/* * output a general addressing mode. */static void putamode P2 (const ADDRESS *, ap, ILEN, len){ IVAL i_val; switch (ap->mode) { case am_immed: oprintf ("#"); /* * Suppress overflow in immediate arguments - * which may occur due to optimization of constants */ if (is_icon (ap->u.offset)) { i_val = ap->u.offset->v.i; switch (len) { case IL1: i_val &= (IVAL) 0x000000ffL; break; case IL2: i_val &= (IVAL) 0x0000ffffL; break; default: break; } oprintf ("%ld", (long) i_val); break; } /*lint -fallthrough */ case am_direct: putconst (ap->u.offset, len); break; case am_areg: oprintf ("A%d", (int) ap->preg - (int) A0); break; case am_dreg: oprintf ("D%d", (int) ap->preg); break; case am_ind: oprintf ("(A%d)", (int) ap->preg - (int) A0); break; case am_ainc: oprintf ("(A%d)+", (int) ap->preg - (int) A0); break; case am_adec: oprintf ("-(A%d)", (int) ap->preg - (int) A0); break; case am_indx: /* allow 32-bit offsets */ putconst (ap->u.offset, IL4); oprintf ("(A%d)", (int) ap->preg - (int) A0); break; case am_indx2: /* allow 32-bit offsets */ putconst (ap->u.offset, IL4); oprintf ("(A%d,D%d.%c)", (int) ap->preg - (int) A0, (int) ap->sreg, 'L'); break; case am_indx3: /* allow 32-bit offsets */ putconst (ap->u.offset, IL4); oprintf ("(A%d,A%d.L)", (int) ap->preg - (int) A0, (int) ap->sreg - (int) A0); break; case am_indx4: /* allow 32-bit offsets */ putconst (ap->u.offset, IL4); oprintf ("(A%d,D%d.%c)", (int) ap->preg - (int) A0, (int) ap->sreg, 'W'); break; case am_indxpc: putconst (ap->u.offset, IL4); oprintf ("(PC)"); break; case am_indx2pc: putconst (ap->u.offset, IL4); oprintf ("(a%d,PC)", (int) ap->preg - (int) A0); break; case am_rmask: put_rmask (ap->u.mask); break; case am_smask: put_smask (ap->u.mask); break; case am_freg: oprintf ("FP%d", (int) ap->preg - (int) FP0); break; case am_line: case am_str: putconst (ap->u.offset, IL4); break; default: FATAL ((__FILE__, "putamode", "illegal address mode %d", ap->mode)); break; }}/* * output a generic instruction. */PRIVATE void put_code P1 (const CODE *, ip){ putop (ip->opcode); putlen (ip->length); if (ip->oper1 != NIL_ADDRESS) { oprintf ("\t"); putamode (ip->oper1, ip->length); if (ip->oper2 != NIL_ADDRESS) { if (ip->opcode == op_line) { oprintf ("%s%s>>>>\t", newline, comment); } else { oprintf (","); } putamode (ip->oper2, ip->length); } } oprintf ("%s", newline);}/* * generate a register mask. */static void put_mask P1 (REGMASK, mask){ REG reg; BOOL pending = FALSE; for (reg = D0; reg <= FP7; reg++) { if (mask & (REGMASK) 1) { if (pending) { oprintf ("/"); } putreg (reg); pending = TRUE; } mask >>= 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -