/
post
157 lines (134 loc) · 4.28 KB
/
post
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
here are some of my fixes for gas 1.38 (and any m68k host):
the problem was that AOFF mode was always generating 0 offsets, the following
example
#APP
.text
movew d1,a0@(two-one)
.lcomm one,2
.lcomm two,2
was being assembled as "movew d1,a0@(0)"
the diffs below incorporate the following:
- diffs from kivinen@JOKER.HUT.FI (Tero Kivinen) fixing a6@(label)
being assembled as PC relative rather than A6 relative.
- diffs from ntmtv!thompson@AI.MIT.EDU (Mike Thompson) for "bkpt #0"
- diff to expr.c:
this requires a little explaination.
the if condition at around line 530 in v1.38 reads
if (expressionP -> X_subtract_symbol == expressionP -> X_add_symbol
|| ( expressionP->X_subtract_symbol->sy_frag==expressionP->X_add_symbol->sy_frag
&& expressionP->X_subtract_symbol->sy_value==expressionP->X_add_symbol->sy_value))
several people have pointed out that this causes seg. faults
and needs to be patched to
if (expressionP -> X_subtract_symbol == expressionP -> X_add_symbol
|| (expressionP->X_subtract_symbol && expressionP->X_add_symbol
&& expressionP->X_subtract_symbol->sy_frag==expressionP->X_add_symbol->sy_frag
&& expressionP->X_subtract_symbol->sy_value==expressionP->X_add_symbol->sy_value))
but doing so always produces zero for expressions such as ``a6@(two-one)''.
(see the #def of "isvar" in m68k.c and its usage for example in the
AOFF case at around line 1509 of m68k.c) , so the
correct condition seems to be just
if (expressionP -> X_subtract_symbol == expressionP -> X_add_symbol)
(as it was in gas 1.34).
with the patches suggested below, it seems to do much better.
---
*** ../gas-1.38/expr.c Fri Jan 4 13:13:00 1991
--- expr.c Tue Feb 5 18:48:54 1991
***************
*** 527,535 ****
* It is faster to re-cancel them to NULL
* than to check for this special case.
*/
! if (expressionP -> X_subtract_symbol == expressionP -> X_add_symbol
! || ( expressionP->X_subtract_symbol->sy_frag==expressionP->X_add_symbol->sy_frag
! && expressionP->X_subtract_symbol->sy_value==expressionP->X_add_symbol->sy_value))
{
expressionP -> X_subtract_symbol = NULL;
expressionP -> X_add_symbol = NULL;
--- 527,533 ----
* It is faster to re-cancel them to NULL
* than to check for this special case.
*/
! if (expressionP -> X_subtract_symbol == expressionP -> X_add_symbol)
{
expressionP -> X_subtract_symbol = NULL;
expressionP -> X_add_symbol = NULL;
*** ../gas-1.38/m68k.c Tue Dec 4 15:50:00 1990
--- m68k.c Wed Feb 6 09:52:38 1991
***************
*** 1258,1265 ****
long t;
t=get_num(opP->con1,80);
! if(t<1 || t>8 || isvar(opP->con1))
! losing++;
}
break;
--- 1258,1271 ----
long t;
t=get_num(opP->con1,80);
! if (s[1]!='s') {
! if(t<1 || t>8 || isvar(opP->con1))
! losing++;
! }
! else {
! if(t<0 || t>7 || isvar(opP->con1))
! losing++;
! }
}
break;
***************
*** 1474,1480 ****
if( !issword(nextword)
|| ( isvar(opP->con1)
&& ( ( opP->con1->e_siz==0
! && flagseen['l']==0)
|| opP->con1->e_siz==3))) {
if(opP->reg==PC)
--- 1480,1486 ----
if( !issword(nextword)
|| ( isvar(opP->con1)
&& ( ( opP->con1->e_siz==0
! && flagseen['l']!=0)
|| opP->con1->e_siz==3))) {
if(opP->reg==PC)
***************
*** 1489,1495 ****
break;
} else {
addword(0x0170);
! add_fix('l',opP->con1,1);
}
} else
addword(0x0170);
--- 1495,1501 ----
break;
} else {
addword(0x0170);
! add_fix('l',opP->con1,0);
}
} else
addword(0x0170);
***************
*** 1976,1984 ****
break;
case 'Q':
! tmpreg=get_num(opP->con1,10);
! if(tmpreg==8)
! tmpreg=0;
install_operand(s[1],tmpreg);
break;
--- 1982,1997 ----
break;
case 'Q':
! if (s[1]!='s') {
! tmpreg=get_num(opP->con1,10);
! if(tmpreg==8)
! tmpreg=0;
! }
! else {
! tmpreg=get_num(opP->con1,20);
! if(tmpreg==8)
! tmpreg=0;
! }
install_operand(s[1],tmpreg);
break;
cheers,