ppcenc.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 973 行 · 第 1/3 页
C
973 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: PowerPC instruction encoding.
*
****************************************************************************/
#include "standard.h"
#include "coderep.h"
#include "opcodes.h"
#include "pattern.h"
#include "symdbg.h"
#include "vergen.h"
#include "reloc.h"
#include "offset.h"
#include "optopts.h"
#include "optlbl.h"
#include "zoiks.h"
#include "model.h"
#include "coff.h"
#include "procdef.h"
#include "cgaux.h"
#include "ppcenc.h"
#include "ppcgen.h"
#include <assert.h>
#include <stdio.h>
extern void DumpInsOnly( instruction * );
extern void DumpString( char * );
extern void DumpPtr( pointer );
extern void DumpInt( int );
extern void DumpNL( void );
extern void DumpGen( struct opcode_entry * );
extern void DumpPtr( void *ptr );
extern void ObjBytes( char *buffer, int size );
extern uint_8 RegTrans( hw_reg_set );
extern void OutLabel( label_handle );
extern void OutReloc( label_handle, ppc_reloc, unsigned );
extern pointer AskForSymLabel( pointer, cg_class );
extern hw_reg_set StackReg( void );
extern hw_reg_set FrameReg( void );
extern name *DeAlias( name * );
extern void TryScrapLabel( code_lbl * );
extern void DbgBlkBeg( dbg_block *blk, offset lc );
extern void DbgBlkEnd( dbg_block *blk, offset lc );
extern offset AskLocation( void );
extern void OutLineNum( unsigned_16 line, bool label_line );
extern void EmitDbgInfo( instruction * );
extern pointer FEAuxInfo( pointer *, aux_class );
extern code_lbl *GetWeirdPPCDotDotLabel( code_lbl * );
extern type_class_def Unsigned[];
extern type_length TypeClassSize[];
extern proc_def *CurrProc;
#define _NameReg( op ) ( (op)->r.arch_index )
#define _IsSigned( type ) ( Unsigned[type] != type )
#define _Emit( ins ) ObjBytes( (char *)&(ins), sizeof( ppc_ins ) )
#define ZERO_SINK 0
#define STACK_REG 1
#define TOC_REG 2
#define VOLATILE_REG 12
#pragma off (unreferenced);
#define _BinaryOpcode( a, b ) { { a, b }, { a, b } }
#define _SignedOpcode( a, b, c, d ) { { a, b }, { c, d } }
// Our table for opcode values is really a list of pairs of
// primary opcode / function code pairs. Their is two entries
// for each opcode in case the sign of the instruction matters;
// for example, for OP_RSHIFT we need to generate either srw or
// sraw. If the sign of the type of the instruction doesn't
// matter, we can just use the _BinaryOpcode macro to create
// identical cases, otherwise we give each pair explicitly.
static opcode BinaryOpcodes[][2][2] = {
_BinaryOpcode( 31, 266 ), /* OP_ADD */
_BinaryOpcode( 31, 266 ), /* OP_EXT_ADD */
_BinaryOpcode( 31, 8 ), /* OP_SUB */
_BinaryOpcode( 31, 8 ), /* OP_EXT_SUB */
_BinaryOpcode( 31, 235 ), /* OP_MUL */
_BinaryOpcode( 31, 235 ), /* OP_EXT_MUL */
_SignedOpcode( 31, 459, 31, 491 ), /* OP_DIV */
_BinaryOpcode( 0, 0 ), /* OP_MOD */
_BinaryOpcode( 31, 28 ), /* OP_AND */
_BinaryOpcode( 31, 444 ), /* OP_OR */
_BinaryOpcode( 31, 316 ), /* OP_XOR */
_SignedOpcode( 31, 536, 31, 792 ), /* OP_RSHIFT */
_BinaryOpcode( 31, 24 ), /* OP_LSHIFT */
_BinaryOpcode( 0, 0 ), /* OP_POW */
_BinaryOpcode( 0, 0 ), /* OP_ATAN2 */
_BinaryOpcode( 0, 0 ), /* OP_FMOD */
};
static opcode FPOpcodes[][2] = {
{ 63, 21 }, /* OP_ADD */
{ 63, 21 }, /* OP_EXT_ADD */
{ 63, 20 }, /* OP_SUB */
{ 63, 20 }, /* OP_EXT_SUB */
{ 63, 25 }, /* OP_MUL */
{ 63, 25 }, /* OP_EXT_MUL */
{ 63, 18 }, /* OP_DIV */
{ 0, 0 }, /* OP_MOD */
{ 0, 0 }, /* OP_AND */
{ 0, 0 }, /* OP_OR */
{ 0, 0 }, /* OP_XOR */
{ 0, 0 }, /* OP_RSHIFT */
{ 0, 0 }, /* OP_LSHIFT */
{ 0, 0 }, /* OP_POW */
{ 0, 0 }, /* OP_ATAN2 */
{ 0, 0 }, /* OP_FMOD */
};
static opcode BinaryImmedOpcodes[] = {
14, /* OP_ADD */
14, /* OP_EXT_ADD */
8, /* OP_SUB */
8, /* OP_EXT_SUB */
7, /* OP_MUL */
7, /* OP_EXT_MUL */
0, /* OP_DIV */
0, /* OP_MOD */
28, /* OP_AND */
24, /* OP_OR */
26, /* OP_XOR */
0, /* OP_RSHIFT */
0, /* OP_LSHIFT */
0, /* OP_POW */
0, /* OP_ATAN2 */
0, /* OP_FMOD */
};
static opcode *FindOpcodes( instruction *ins )
/**********************************************/
{
opcode *opcodes;
if( _IsFloating( ins->type_class ) ) {
opcodes = &FPOpcodes[ins->head.opcode - FIRST_BINARY_OP][0];
} else {
opcodes = &BinaryOpcodes[ins->head.opcode - FIRST_BINARY_OP][_IsSigned( ins->type_class )][0];
}
return( opcodes );
}
static opcode *FindImmedOpcodes( instruction *ins )
/***************************************************/
{
opcode *opcodes;
opcodes = &BinaryImmedOpcodes[ins->head.opcode - FIRST_BINARY_OP];
if( *opcodes == 0 ) {
_Zoiks( ZOIKS_091 );
}
return( opcodes );
}
extern void GenFPOPINS( opcode op1, opcode op2, reg_index a, reg_index c, reg_index d )
//*****************************************************************************************
{
ppc_ins encoding;
encoding = _Op1( op1 ) | _A( a ) | _C( c ) | _D( d ) | _Op2( op2 );
_Emit( encoding );
}
extern void GenOPINS( opcode op1, opcode op2, reg_index a, reg_index b, reg_index s )
//***************************************************************************************
{
ppc_ins encoding;
encoding = _Op1( op1 ) | _A( a ) | _B( b ) | _S( s ) | _Op2( op2 );
_Emit( encoding );
}
extern void GenOPIMM( opcode op1, reg_index d, reg_index a, signed_16 immed )
//*******************************************************************************
{
ppc_ins encoding;
encoding = _Op1( op1 ) | _D( d ) | _A( a ) | _SignedImmed( immed );
_Emit( encoding );
}
extern void GenMTSPR( reg_index d, uint_32 spr, bool from )
//*************************************************************
{
ppc_ins encoding;
encoding = _Op1( 31 ) | _Op2( 467 );
if( from ) {
encoding = _Op1( 31 ) | _Op2( 339 );
}
encoding |= _D( d ) | _SPR( spr );
_Emit( encoding );
}
extern void GenMEMINS( opcode op, reg_index d, reg_index i, signed_16 displacement )
/**************************************************************************************/
{
ppc_ins encoding;
encoding = _Op1( op ) | _D( d ) | _A( i ) | _SignedImmed( displacement );
_Emit( encoding );
}
extern void GenBRANCH( opcode op, pointer label, bool link, bool absolute )
/*****************************************************************************/
{
ppc_ins encoding;
int_32 loc;
loc = AskLocation();
encoding = _Op1( op ) | _AA( absolute ) | _LK( link ) | _BranchImmed( -loc );
OutReloc( label, PPC_RELOC_BRANCH, 0 );
_Emit( encoding );
}
extern void GenCONDBR( opcode op, opcode bo, opcode bi, pointer label )
/*************************************************************************/
{
ppc_ins encoding;
encoding = _Op1( op ) | _S( bo ) | _A( bi );
OutReloc( label, PPC_RELOC_BRANCH_COND, 0 );
_Emit( encoding );
}
extern void GenCMP( opcode op, opcode op2, reg_index a, reg_index b )
/***********************************************************************/
{
ppc_ins encoding;
encoding = _Op1( op ) | _A( a ) | _B( b ) | _Op2( op2 );
_Emit( encoding );
}
extern void GenCMPIMM( opcode op, reg_index a, signed_16 imm )
/****************************************************************/
{
ppc_ins encoding;
encoding = _Op1( op ) | _A( a ) | _SignedImmed( imm );
_Emit( encoding );
}
extern void GenRAWINS( uint_32 encoding )
/*******************************************/
{
_Emit( encoding );
}
static pointer symLabel( name *mem )
/***********************************/
{
return( AskForSymLabel( mem->v.symbol, mem->m.memory_type ) );
}
extern type_length TempLocation( name *temp )
/************************************************/
{
name *base;
type_length offset;
assert( temp->n.class == N_TEMP );
base = DeAlias( temp );
if( base->t.location == NO_LOCATION ) {
_Zoiks( ZOIKS_030 );
}
offset = CurrProc->targ.stack_map.locals.start;
if( temp->t.temp_flags & STACK_PARM ) {
offset = CurrProc->targ.frame_size + STACK_HEADER_SIZE;
}
return( offset + temp->t.location + temp->v.offset - base->v.offset );
}
static void doCall( instruction *ins )
/****************************************/
{
pointer sym;
risc_byte_seq *code;
ppc_ins encoding;
code_lbl *lbl;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?