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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
This file describes the implementation notes of the GNU C Compiler for
the National Semiconductor 32032 chip (and 32000 family).
Much of this file was obsolete. It described restrictions caused by
bugs in early versions of of the ns32032 chip and by bugs in sequent
assemblers and linkers of the time.
Many (all?) of the chip bugs were fixed in later revisions and
certainly fixed by later chips in the same series (ns32332 and
ns32532).
Conditional code to support sequent assembler and/or linker restrictions
has not been removed deliberately, but has probably not been tested in
a *very* long time.
Support for one sequent assembler bug has *not* been retained.
It was necessary to say:
addr _x,rn
cmpd _p,rn
rather than:
cmpd _p,@_x
This used to be forced by the use of "rmn" register constraints rather
than "g". This is bad for other platforms which do not have this
restraint.
It is likely that there are no Balance 8000's still in operation, but
if there are and the assembler bug was never fixed then the easiest
way to run gcc would be to also run gas.
The code required by the sequent assembler is still generated when the
-fpic flag is in effect and this is forced by the appropriate
definition of LEGITIMATE_PIC_OPERAND_P. If support for the old sequent
assembler bug is required, then this could be achieved by adding the
test from LEGITIMATE_PIC_OPERAND to the GO_IF_LEGITIMATE_ADDRESS
definition. Of course, this should be conditional on something in the
sequent.h config file.
The original contents of this file appear below as an historical note.
SEQUENT_ADDRESS_BUG mentioned below has been replaced by
INDEX_RATHER_THAN_BASE. Note that merlin.h still defines
SEQUENT_ADDRESS_BUG even though it is not used anywhere. Since it has
been like this for a long time, presumably either the
SEQUENT_ADDRESS_BUG is not required for the merlin, or no one is using
gcc on the merlin anymore.
HISTORICAL NOTE
The 32032 machine description and configuration file for this compiler
is, for NS32000 family machine, primarily machine independent.
However, since this release still depends on vendor-supplied
assemblers and linkers, the compiler must obey the existing
conventions of the actual machine to which this compiler is targeted.
In this case, the actual machine which this compiler was targeted to
is a Sequent Balance 8000, running DYNIX 2.1.
The assembler for DYNIX 2.1 (and DYNIX 3.0, alas) does not cope with
the full generality of the addressing mode REGISTER RELATIVE.
Specifically, it generates incorrect code for operands of the
following form:
sym(rn)
Where `rn' is one of the general registers. Correct code is generated
for operands of the form
sym(pn)
where `pn' is one of the special processor registers (sb, fp, or sp).
An equivalent operand can be generated by the form
sym[rn:b]
although this addressing mode is about twice as slow on the 32032.
The more efficient addressing mode is controlled by defining the
constant SEQUENT_ADDRESS_BUG to 0. It is currently defined to be 1.
Another bug in the assembler makes it impossible to compute with
explicit addresses. In order to compute with a symbolic address, it
is necessary to load that address into a register using the "addr"
instruction. For example, it is not possible to say
cmpd _p,@_x
Rather one must say
addr _x,rn
cmpd _p,rn
The ns32032 chip has a number of known bugs. Any attempt to make the
compiler unaware of these deficiencies will surely bring disaster.
The current list of know bugs are as follows (list provided by Richard
Stallman):
1) instructions with two overlapping operands in memory
(unlikely in C code, perhaps impossible).
2) floating point conversion instructions with constant
operands (these may never happen, but I'm not certain).
3) operands crossing a page boundary. These can be prevented
by setting the flag in tm.h that requires strict alignment.
4) Scaled indexing in an insn following an insn that has a read-write
operand in memory. This can be prevented by placing a no-op in
between. I, Michael Tiemann, do not understand what exactly is meant
by `read-write operand in memory'. If this is referring to the special
TOS mode, for example "addd 5,tos" then one need not fear, since this
will never be generated. However, is this includes "addd 5,-4(fp)"
then there is room for disaster. The Sequent compiler does not insert
a no-op for code involving the latter, and I have been informed that
Sequent is aware of this list of bugs, so I must assume that it is not
a problem.
5) The 32032 cannot shift by 32 bits. It shifts modulo the word size
of the operand. Therefore, for 32-bit operations, 32-bit shifts are
interpreted as zero bit shifts. 32-bit shifts have been removed from
the compiler, but future hackers must be careful not to reintroduce
them.
6) The ns32032 is a very slow chip; however, some instructions are
still very much slower than one might expect. For example, it is
almost always faster to double a quantity by adding it to itself than
by shifting it by one, even if that quantity is deep in memory. The
MOVM instruction has a 20-cycle setup time, after which it moves data
at about the speed that normal moves would. It is also faster to use
address generation instructions than shift instructions for left
shifts less than 4. I do not claim that I generate optimal code for all
given patterns, but where I did escape from National's "clean
architecture", I did so because the timing specification from the data
book says that I will win if I do. I suppose this is called the
"performance gap".
Signed bitfield extraction has not been implemented. It is not
provided by the NS32032, and while it is most certainly possible to do
better than the standard shift-left/shift-right sequence, it is also
quite hairy. Also, since signed bitfields do not yet exist in C, this
omission seems relatively harmless.
Zero extractions could be better implemented if it were possible in
GCC to provide sized zero extractions: i.e. a byte zero extraction
would be allowed to yield a byte result. The current implementation
of GCC manifests 68000-ist thinking, where bitfields are extracted
into a register, and automatically sign/zero extended to fill the
register. See comments in ns32k.md around the "extzv" insn for more
details.
It should be noted that while the NS32000 family was designed to
provide odd-aligned addressing capability for multi-byte data (also
provided by the 68020, but not by the 68000 or 68010), many machines
do not opt to take advantage of this. For example, on the sequent,
although there is no advantage to long-word aligning word data, shorts
must be int-aligned in structs. This is an example of another
machine-specific machine dependency.
Because the ns32032 is has a coherent byte-order/bit-order
architecture, many instructions which would be different for
68000-style machines, fold into the same instruction for the 32032.
The classic case is push effective address, where it does not matter
whether one is pushing a long, word, or byte address. They all will
push the same address.
The macro FUNCTION_VALUE_REGNO_P is probably not sufficient, what is
needed is FUNCTION_VALUE_P, which also takes a MODE parameter. In
this way it will be possible to determine more exactly whether a
register is really a function value register, or just one that happens
to look right.
|