-
Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathfpfixup.c
124 lines (112 loc) · 4.23 KB
/
fpfixup.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/****************************************************************************
*
* 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;
}