1 |
38 |
julius |
/* Definitions of target machine for GNU compiler. TMS320C[34]x
|
2 |
|
|
Copyright (C) 2002, 2004, 2007 Free Software Foundation, Inc.
|
3 |
|
|
|
4 |
|
|
Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz)
|
5 |
|
|
and Herman Ten Brugge (Haj.Ten.Brugge@net.HCC.nl).
|
6 |
|
|
|
7 |
|
|
This file is part of GCC.
|
8 |
|
|
|
9 |
|
|
GCC is free software; you can redistribute it and/or modify
|
10 |
|
|
it under the terms of the GNU General Public License as published by
|
11 |
|
|
the Free Software Foundation; either version 3, or (at your option)
|
12 |
|
|
any later version.
|
13 |
|
|
|
14 |
|
|
GCC is distributed in the hope that it will be useful,
|
15 |
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17 |
|
|
GNU General Public License for more details.
|
18 |
|
|
|
19 |
|
|
You should have received a copy of the GNU General Public License
|
20 |
|
|
along with GCC; see the file COPYING3. If not see
|
21 |
|
|
. */
|
22 |
|
|
|
23 |
|
|
/* C4x wants 1- and 2-word float modes, in its own peculiar format.
|
24 |
|
|
FIXME: Give this port a way to get rid of SFmode, DFmode, and all
|
25 |
|
|
the other modes it doesn't use. */
|
26 |
|
|
FLOAT_MODE (QF, 1, c4x_single_format);
|
27 |
|
|
FLOAT_MODE (HF, 2, c4x_extended_format);
|
28 |
|
|
RESET_FLOAT_FORMAT (SF, 0); /* not used */
|
29 |
|
|
RESET_FLOAT_FORMAT (DF, 0); /* not used */
|
30 |
|
|
|
31 |
|
|
/* Add any extra modes needed to represent the condition code.
|
32 |
|
|
|
33 |
|
|
On the C4x, we have a "no-overflow" mode which is used when an ADD,
|
34 |
|
|
SUB, NEG, or MPY insn is used to set the condition code. This is
|
35 |
|
|
to prevent the combiner from optimizing away a following CMP of the
|
36 |
|
|
result with zero when a signed conditional branch or load insn
|
37 |
|
|
follows.
|
38 |
|
|
|
39 |
|
|
The problem is a subtle one and deals with the manner in which the
|
40 |
|
|
negative condition (N) flag is used on the C4x. This flag does not
|
41 |
|
|
reflect the status of the actual result but of the ideal result had
|
42 |
|
|
no overflow occurred (when considering signed operands).
|
43 |
|
|
|
44 |
|
|
For example, 0x7fffffff + 1 => 0x80000000 Z=0 V=1 N=0 C=0. Here
|
45 |
|
|
the flags reflect the untruncated result, not the actual result.
|
46 |
|
|
While the actual result is less than zero, the N flag is not set
|
47 |
|
|
since the ideal result of the addition without truncation would
|
48 |
|
|
have been positive.
|
49 |
|
|
|
50 |
|
|
Note that the while the N flag is handled differently to most other
|
51 |
|
|
architectures, the use of it is self consistent and is not the
|
52 |
|
|
cause of the problem.
|
53 |
|
|
|
54 |
|
|
Logical operations set the N flag to the MSB of the result so if
|
55 |
|
|
the result is negative, N is 1. However, integer and floating
|
56 |
|
|
point operations set the N flag to be the MSB of the result
|
57 |
|
|
exclusive ored with the overflow (V) flag. Thus if an overflow
|
58 |
|
|
occurs and the result does not have the MSB set (i.e., the result
|
59 |
|
|
looks like a positive number), the N flag is set. Conversely, if
|
60 |
|
|
an overflow occurs and the MSB of the result is set, N is set to 0.
|
61 |
|
|
Thus the N flag represents the sign of the result if it could have
|
62 |
|
|
been stored without overflow but does not represent the apparent
|
63 |
|
|
sign of the result. Note that most architectures set the N flag to
|
64 |
|
|
be the MSB of the result.
|
65 |
|
|
|
66 |
|
|
The C4x approach to setting the N flag simplifies signed
|
67 |
|
|
conditional branches and loads which only have to test the state of
|
68 |
|
|
the N flag, whereas most architectures have to look at both the N
|
69 |
|
|
and V flags. The disadvantage is that there is no flag giving the
|
70 |
|
|
status of the sign bit of the operation. However, there are no
|
71 |
|
|
conditional load or branch instructions that make use of this
|
72 |
|
|
feature (e.g., BMI---branch minus) instruction. Note that BN and
|
73 |
|
|
BLT are identical in the C4x.
|
74 |
|
|
|
75 |
|
|
To handle the problem where the N flag is set differently whenever
|
76 |
|
|
there is an overflow we use a different CC mode, CC_NOOVmode which
|
77 |
|
|
says that the CC reflects the comparison of the result against zero
|
78 |
|
|
if no overflow occurred.
|
79 |
|
|
|
80 |
|
|
For example,
|
81 |
|
|
|
82 |
|
|
[(set (reg:CC_NOOV 21)
|
83 |
|
|
(compare:CC_NOOV (minus:QI (match_operand:QI 1 "src_operand" "")
|
84 |
|
|
(match_operand:QI 2 "src_operand" ""))
|
85 |
|
|
(const_int 0)))
|
86 |
|
|
(set (match_operand:QI 0 "ext_reg_operand" "")
|
87 |
|
|
(minus:QI (match_dup 1)
|
88 |
|
|
(match_dup 2)))]
|
89 |
|
|
|
90 |
|
|
Note that there is no problem for insns that don't return a result
|
91 |
|
|
like CMP, since the CC reflects the effect of operation.
|
92 |
|
|
|
93 |
|
|
An example of a potential problem is when GCC
|
94 |
|
|
converts (LTU (MINUS (0x80000000) (0x7fffffff) (0x80000000)))
|
95 |
|
|
to (LEU (MINUS (0x80000000) (0x7fffffff) (0x7fffffff)))
|
96 |
|
|
to (GE (MINUS (0x80000000) (0x7fffffff) (0x00000000)))
|
97 |
|
|
|
98 |
|
|
Now (MINUS (0x80000000) (0x7fffffff)) returns 0x00000001 but the
|
99 |
|
|
C4x sets the N flag since the result without overflow would have
|
100 |
|
|
been 0xffffffff when treating the operands as signed integers.
|
101 |
|
|
Thus (GE (MINUS (0x80000000) (0x7fffffff) (0x00000000))) sets the N
|
102 |
|
|
flag but (GE (0x00000001)) does not set the N flag.
|
103 |
|
|
|
104 |
|
|
The upshot is that we cannot use signed branch and conditional
|
105 |
|
|
load instructions after an add, subtract, neg, abs or multiply.
|
106 |
|
|
We must emit a compare insn to check the result against 0. */
|
107 |
|
|
|
108 |
|
|
CC_MODE (CC_NOOV);
|