mirror of
https://github.com/NishiOwO/JWasm.git
synced 2025-04-21 16:54:39 +00:00
125 lines
4.3 KiB
C
125 lines
4.3 KiB
C
/****************************************************************************
|
|
*
|
|
* 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: FP fixups for 16-bit code. These fixups allow the linker
|
|
* or program loader to replace FP instructions by calls to an FP emulation
|
|
* library.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "globals.h"
|
|
#include "parser.h"
|
|
#include "extern.h"
|
|
#include "fixup.h"
|
|
#include "mangle.h"
|
|
#include "myassert.h"
|
|
#include "segment.h"
|
|
#include "omf.h"
|
|
#include "omfspec.h"
|
|
|
|
enum fp_patches {
|
|
FPP_WAIT,
|
|
FPP_NORMAL,
|
|
FPP_ES, /* last 6 entries match order of ASSUME_ES, ... */
|
|
FPP_CS,
|
|
FPP_SS,
|
|
FPP_DS,
|
|
FPP_FS,
|
|
FPP_GS
|
|
};
|
|
|
|
/* FP 16-bit fixup names.
|
|
* Known by MS VC, Open Watcom, Borland and Digital Mars:
|
|
* FIWRQQ, FIDRQQ, FIERQQ, FICRQQ, FISRQQ, FIARQQ, FIFRQQ, FIGRQQ,
|
|
* FJCRQQ, FJSRQQ, FJARQQ, FJFRQQ, FJGRQQ
|
|
*/
|
|
|
|
static const uint_16 patchmask = 0xF8FF;
|
|
|
|
static const char patchchr2[] = {
|
|
'W', 'D', 'E', 'C', 'S', 'A', 'F', 'G'
|
|
};
|
|
|
|
void AddFloatingPointEmulationFixup( struct code_info *CodeInfo )
|
|
/***************************************************************/
|
|
{
|
|
int i;
|
|
enum fp_patches patch;
|
|
struct asym *sym[2];
|
|
struct fixup *fixup;
|
|
int_32 data;
|
|
char name[8] = "F__RQQ";
|
|
|
|
DebugMsg(("AddFloatingPointEmulationFixup enter, token=%u, regoverride=%d\n", CodeInfo->token, CodeInfo->prefix.RegOverride ));
|
|
|
|
if( CodeInfo->token == T_FWAIT ) {
|
|
patch = FPP_WAIT;
|
|
} else if ( CodeInfo->prefix.RegOverride == EMPTY ) {
|
|
patch = FPP_NORMAL;
|
|
} else {
|
|
patch = CodeInfo->prefix.RegOverride + 2;
|
|
}
|
|
|
|
/* emit 1-2 externals for the patch if not done already */
|
|
for ( i = 0; i < 2; i++ ) {
|
|
sym[i] = NULL;
|
|
if ( patchmask & ( 1 << ( i*8+patch ) ) ) {
|
|
name[1] = 'I' + i;
|
|
name[2] = patchchr2[patch];
|
|
sym[i] = SymSearch( name );
|
|
if( sym[i] == NULL || sym[i]->state == SYM_UNDEFINED ) {
|
|
sym[i] = MakeExtern( name, MT_FAR, NULL, sym[i], USE16 );
|
|
sym[i]->langtype = LANG_NONE;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* no need for fixups if no object file is written */
|
|
if ( write_to_file == FALSE )
|
|
return;
|
|
|
|
/* make sure the next 3 bytes in code stream aren't separated.
|
|
* The first fixup covers bytes $+0 and $+1, the (possible) second
|
|
* fixup covers bytes $+1 and $+2.
|
|
*/
|
|
if( Options.output_format == OFORMAT_OMF &&
|
|
( CurrSeg->e.seginfo->current_loc - CurrSeg->e.seginfo->start_loc + 3 ) > MAX_LEDATA_THRESHOLD )
|
|
omf_FlushCurrSeg();
|
|
|
|
for ( i = 0; i < 2 ; i++ ) {
|
|
if ( sym[i] ) {
|
|
fixup = CreateFixup( sym[i], FIX_OFF16, OPTJ_NONE );
|
|
fixup->frame_type = FRAME_TARG;
|
|
/* assume locofs has been set inside CreateFixup() */
|
|
//fixup->locofs = CurrSeg->e.seginfo->current_loc + i;
|
|
fixup->locofs += i;
|
|
data = 0;
|
|
store_fixup( fixup, CurrSeg, &data );
|
|
}
|
|
}
|
|
return;
|
|
}
|