fis-gtm/sr_alpha/emit_code_sp.c

279 lines
6.2 KiB
C

/****************************************************************
* *
* Copyright 2001, 2009 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_string.h"
#include "cgp.h"
#include "compiler.h"
#include <rtnhdr.h>
#include "list_file.h"
#include <emit_code.h>
GBLREF uint4 code_buf[]; /* Instruction buffer */
GBLREF int code_idx; /* Index into code_buf */
GBLREF char cg_phase; /* Current compiler phase */
GBLREF int4 curr_addr;
#ifdef DEBUG
GBLREF unsigned char *obpt; /* output buffer index */
GBLREF unsigned char outbuf[]; /* assembly language output buffer */
static unsigned int ains; /* assembler instruction (binary) */
#endif
/* Used by emit_base_offset to extract offset parts */
int alpha_adjusted_upper(int offset)
{
int upper;
upper = (offset >> 16) & 0xFFFF;
if (offset & 0x8000)
upper = (upper + 1) & 0xFFFF;
return upper;
}
void emit_base_offset(int base, int offset)
{
/* NOTE: emit_base_offset does not advance past its last
generated instruction because that instruction is
incomplete; it contains only a base and offset -- the
rt and opcode field are left empty for use by the caller. */
int upper, low, source;
switch (cg_phase)
{
#ifdef DEBUG
case CGP_ASSEMBLY:
#endif
case CGP_ADDR_OPT:
case CGP_APPROX_ADDR:
case CGP_MACHINE:
assert(base >= 0 && base <= 31);
source = base;
upper = alpha_adjusted_upper(offset);
if (0 != upper)
{
code_buf[code_idx++] = ALPHA_INS_LDAH
| (GTM_REG_CODEGEN_TEMP << ALPHA_SHIFT_RA)
| (source << ALPHA_SHIFT_RB)
| (upper & ALPHA_MASK_DISP) << ALPHA_SHIFT_DISP;
source = GTM_REG_CODEGEN_TEMP;
}
low = offset & 0xFFFF;
code_buf[code_idx] = source << ALPHA_SHIFT_RB
| (low & ALPHA_MASK_DISP) << ALPHA_SHIFT_DISP;
break;
default:
GTMASSERT;
}
}
#ifdef DEBUG
void fmt_ra()
{
*obpt++ = 'r';
obpt = i2asc(obpt, GET_RA(ains));
}
void fmt_ra_rb()
{
fmt_ra();
*obpt++ = ',';
*obpt++;
*obpt++ = 'r';
obpt = i2asc(obpt, GET_RB(ains));
}
void fmt_ra_rb_rc()
{
fmt_ra_rb();
*obpt++ = ',';
*obpt++;
*obpt++ = 'r';
obpt = i2asc(obpt, GET_RC(ains));
}
void fmt_ra_mem()
{
fmt_ra();
*obpt++ = ',';
obpt++;
*obpt++ = '0';
*obpt++ = 'x';
obpt += i2hex_nofill(GET_MEMDISP(ains), obpt, 6);
*obpt++ = '(';
*obpt++ = 'r';
obpt = i2asc(obpt, GET_RB(ains));
*obpt++ = ')';
}
void fmt_ra_brdisp()
{
fmt_ra();
*obpt++ = ',';
obpt++;
*obpt++ = '0';
*obpt++ = 'x';
obpt += i2hex_nofill(GET_BRDISP(ains) * 4, obpt, 6);
}
void format_machine_inst(void)
{
int instindx;
for (instindx = 0; instindx < code_idx; instindx++)
{
list_chkpage();
obpt = &outbuf[0];
memset(obpt, SP, ASM_OUT_BUFF);
obpt += 10;
i2hex((curr_addr - SIZEOF(rhdtyp)), (uchar_ptr_t)obpt, 8);
curr_addr += 4;
obpt += 10;
i2hex(code_buf[instindx], (uchar_ptr_t)obpt, 8);
obpt += 10;
ains = code_buf[instindx];
switch(GET_OPCODE(ains))
{
case 0x8:
memcpy(obpt, LDA_INST, SIZEOF(LDA_INST) - 1);
obpt += OPSPC;
fmt_ra_mem();
break;
case 0x9:
memcpy(obpt, LDAH_INST, SIZEOF(LDAH_INST) - 1);
obpt += OPSPC;
fmt_ra_mem();
break;
case 0x10:
/* Note opcodes 0x10, 0x11, have overlapping functions but none that we generate
so we can combine their disassembly.
*/
case 0x11:
switch(GET_FUNC(ains))
{
case 0x0: /* main opcode 0x10 */
memcpy(obpt, ADDL_INST, SIZEOF(ADDL_INST) - 1);
break;
case 0x9: /* main opcode 0x10 */
memcpy(obpt, SUBL_INST, SIZEOF(SUBL_INST) - 1);
break;
case 0x29: /* main opcode 0x10 */
memcpy(obpt, SUBQ_INST, SIZEOF(SUBQ_INST) - 1);
break;
case 0x20: /* main opcode 0x11 */
memcpy(obpt, BIS_INST, SIZEOF(BIS_INST) - 1);
break;
default:
GTMASSERT;
}
obpt += OPSPC;
fmt_ra_rb_rc();
break;
case 0x1a:
switch(GET_MEMDISP(ains) & 0x3)
{
case 0x0:
memcpy(obpt, JMP_INST, SIZEOF(JMP_INST) - 1);
break;
case 0x1:
memcpy(obpt, JSR_INST, SIZEOF(JSR_INST) - 1);
break;
case 0x2:
memcpy(obpt, RET_INST, SIZEOF(RET_INST) - 1);
break;
default:
GTMASSERT;
}
obpt += OPSPC;
fmt_ra_rb();
break;
case 0x28:
memcpy(obpt, LDL_INST, SIZEOF(LDL_INST) - 1);
obpt += OPSPC;
fmt_ra_mem();
break;
case 0x29:
memcpy(obpt, LDQ_INST, SIZEOF(LDQ_INST) - 1);
obpt += OPSPC;
fmt_ra_mem();
break;
case 0x2c:
memcpy(obpt, STL_INST, SIZEOF(STL_INST) - 1);
obpt += OPSPC;
fmt_ra_mem();
break;
case 0x2d:
memcpy(obpt, STQ_INST, SIZEOF(STQ_INST) - 1);
obpt += OPSPC;
fmt_ra_mem();
break;
case 0x30:
memcpy(obpt, BR_INST, SIZEOF(BR_INST) - 1);
obpt += OPSPC;
fmt_ra_brdisp();
break;
case 0x34:
memcpy(obpt, BSR_INST, SIZEOF(BSR_INST) - 1);
obpt += OPSPC;
fmt_ra_brdisp();
break;
case 0x38:
memcpy(obpt, BLBC_INST, SIZEOF(BLBC_INST) - 1);
obpt += OPSPC;
fmt_ra_brdisp();
break;
case 0x39:
memcpy(obpt, BEQ_INST, SIZEOF(BEQ_INST) - 1);
obpt += OPSPC;
fmt_ra_brdisp();
break;
case 0x3a:
memcpy(obpt, BLT_INST, SIZEOF(BLT_INST) - 1);
obpt += OPSPC;
fmt_ra_brdisp();
break;
case 0x3b:
memcpy(obpt, BLE_INST, SIZEOF(BLE_INST) - 1);
obpt += OPSPC;
fmt_ra_brdisp();
break;
case 0x3c:
memcpy(obpt, BLBS_INST, SIZEOF(BLBS_INST) - 1);
obpt += OPSPC;
fmt_ra_brdisp();
break;
case 0x3d:
memcpy(obpt, BNE_INST, SIZEOF(BNE_INST) - 1);
obpt += OPSPC;
fmt_ra_brdisp();
break;
case 0x3e:
memcpy(obpt, BGE_INST, SIZEOF(BGE_INST) - 1);
obpt += OPSPC;
fmt_ra_brdisp();
break;
case 0x3f:
memcpy(obpt, BGT_INST, SIZEOF(BGT_INST) - 1);
obpt += OPSPC;
fmt_ra_brdisp();
break;
default: /* Not an instruction but a constant */
memcpy(obpt, CONSTANT, SIZEOF(CONSTANT) - 1);
obpt += SIZEOF(CONSTANT) - 1;
i2hex(ains, obpt, 8);
obpt += 8;
}
emit_eoi();
}
}
#endif