OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [sw/] [gcc-zippatch.patch] - Blame information for rev 209

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 202 dgisselq
diff -Naur '--exclude=*.swp' gcc-6.2.0/config.sub gcc-6.2.0-zip/config.sub
2
--- gcc-6.2.0/config.sub        2015-12-31 16:13:28.000000000 -0500
3
+++ gcc-6.2.0-zip/config.sub    2017-01-11 11:07:21.116065311 -0500
4
@@ -355,6 +355,14 @@
5
        xscaleel)
6
                basic_machine=armel-unknown
7 102 dgisselq
                ;;
8 202 dgisselq
+       zip-*-linux*)
9
+               basic_machine=zip
10
+               os=-linux
11
+               ;;
12
+       zip*)
13
+               basic_machine=zip-unknown
14
+               os=-none
15
+               ;;
16 102 dgisselq
 
17 202 dgisselq
        # We use `pc' rather than `unknown'
18
        # because (1) that's what they normally are, and
19
diff -Naur '--exclude=*.swp' gcc-6.2.0/configure gcc-6.2.0-zip/configure
20
--- gcc-6.2.0/configure 2016-03-17 18:54:19.000000000 -0400
21
+++ gcc-6.2.0-zip/configure     2017-02-06 21:54:22.244807700 -0500
22
@@ -3548,6 +3548,44 @@
23
   ft32-*-*)
24
     noconfigdirs="$noconfigdirs ${libgcj}"
25
     ;;
26
+  zip*)
27
+    noconfigdirs="$noconfigdirs ${libgcj}"
28
+    noconfigdirs="$noconfigdirs target-boehm-gc"
29
+    noconfigdirs="$noconfigdirs target-libgfortran"
30
+    # noconfigdirs="$noconfigdirs target-libsanitizer"
31
+    # noconfigdirs="$noconfigdirs target-libada"
32
+    # noconfigdirs="$noconfigdirs target-libatomic"
33
+    # noconfigdirs="$noconfigdirs target-libcilkrts"
34
+    # noconfigdirs="$noconfigdirs target-libitm"
35
+    # noconfigdirs="$noconfigdirs target-libquadmath"
36
+    # noconfigdirs="$noconfigdirs target-libstdc++-v3"
37
+    # noconfigdirs="$noconfigdirs target-libssp"
38
+    # noconfigdirs="$noconfigdirs target-libgo"
39
+    # noconfigdirs="$noconfigdirs target-libgomp"
40
+    # noconfigdirs="$noconfigdirs target-libvtv"
41
+    # noconfigdirs="$noconfigdirs target-libobjc"
42
+       # target-libgcc
43
+       #       target-liboffloadmic
44
+       #       target-libmpx   # Only gets enabled by request
45
+       #       target-libbacktrace
46
+       #       ${libgcj}
47
+       #       target-boehm-gc
48
+       #       target-libada
49
+       #       target-libatomic
50
+       #       target-libcilkrts
51
+       #       target-libgfortran
52
+       #       target-libgo
53
+       #       target-libgomp
54
+       #       target-libitm
55
+       #       target-libobjc
56
+       #       target-libquadmath
57
+       #       target-libsanitizer
58
+       #       target-libstdc++-v3
59
+       #       target-libssp
60
+       #       target-libvtv
61
+       # target-libgloss
62
+       # target-newlib
63
+    ;;
64
   *-*-lynxos*)
65
     noconfigdirs="$noconfigdirs ${libgcj}"
66
     ;;
67
@@ -3575,6 +3613,9 @@
68
     *-*-aix*)
69
        noconfigdirs="$noconfigdirs target-libgo"
70
        ;;
71
+    zip*)
72
+       noconfigdirs="$noconfigdirs target-libgo"
73
+       ;;
74
     esac
75
 fi
76
 
77
@@ -3971,6 +4012,9 @@
78 102 dgisselq
   vax-*-*)
79
     noconfigdirs="$noconfigdirs target-newlib target-libgloss"
80
     ;;
81
+  zip*)
82
+    noconfigdirs="$noconfigdirs target-libffi target-boehm-gc gdb gprof"
83 202 dgisselq
+    ;;
84 102 dgisselq
 esac
85
 
86
 # If we aren't building newlib, then don't build libgloss, since libgloss
87 202 dgisselq
@@ -6785,16 +6829,16 @@
88
 # CFLAGS_FOR_TARGET and CXXFLAGS_FOR_TARGET.
89
 if test "x$CFLAGS_FOR_TARGET" = x; then
90
   if test "x${is_cross_compiler}" = xyes; then
91
-    CFLAGS_FOR_TARGET="-g -O2"
92
+    CFLAGS_FOR_TARGET="-O3"
93
   else
94
     CFLAGS_FOR_TARGET=$CFLAGS
95
     case " $CFLAGS " in
96
-      *" -O2 "*) ;;
97
-      *) CFLAGS_FOR_TARGET="-O2 $CFLAGS_FOR_TARGET" ;;
98
+      *" -O3 "*) ;;
99
+      *) CFLAGS_FOR_TARGET="-O3 $CFLAGS_FOR_TARGET" ;;
100
     esac
101
     case " $CFLAGS " in
102
       *" -g "* | *" -g3 "*) ;;
103
-      *) CFLAGS_FOR_TARGET="-g $CFLAGS_FOR_TARGET" ;;
104
+      *) CFLAGS_FOR_TARGET="$CFLAGS_FOR_TARGET" ;;
105
     esac
106
   fi
107
 fi
108
@@ -6802,16 +6846,16 @@
109
 
110
 if test "x$CXXFLAGS_FOR_TARGET" = x; then
111
   if test "x${is_cross_compiler}" = xyes; then
112
-    CXXFLAGS_FOR_TARGET="-g -O2"
113
+    CXXFLAGS_FOR_TARGET="-O3"
114
   else
115
     CXXFLAGS_FOR_TARGET=$CXXFLAGS
116
     case " $CXXFLAGS " in
117
-      *" -O2 "*) ;;
118
-      *) CXXFLAGS_FOR_TARGET="-O2 $CXXFLAGS_FOR_TARGET" ;;
119
+      *" -O3 "*) ;;
120
+      *) CXXFLAGS_FOR_TARGET="-O3 $CXXFLAGS_FOR_TARGET" ;;
121
     esac
122
     case " $CXXFLAGS " in
123
       *" -g "* | *" -g3 "*) ;;
124
-      *) CXXFLAGS_FOR_TARGET="-g $CXXFLAGS_FOR_TARGET" ;;
125
+      *) CXXFLAGS_FOR_TARGET="$CXXFLAGS_FOR_TARGET" ;;
126
     esac
127
   fi
128
 fi
129
diff -Naur '--exclude=*.swp' gcc-6.2.0/configure.ac gcc-6.2.0-zip/configure.ac
130
--- gcc-6.2.0/configure.ac      2016-03-17 18:54:19.000000000 -0400
131
+++ gcc-6.2.0-zip/configure.ac  2017-01-10 12:43:23.819301273 -0500
132
@@ -884,6 +884,9 @@
133
   ft32-*-*)
134
     noconfigdirs="$noconfigdirs ${libgcj}"
135
     ;;
136
+  zip*)
137
+    noconfigdirs="$noconfigdirs ${libgcj}"
138
+    ;;
139
   *-*-lynxos*)
140
     noconfigdirs="$noconfigdirs ${libgcj}"
141
     ;;
142
@@ -911,6 +914,9 @@
143
     *-*-aix*)
144
        noconfigdirs="$noconfigdirs target-libgo"
145
        ;;
146
+    zip*)
147
+       noconfigdirs="$noconfigdirs target-libgo"
148
+       ;;
149
     esac
150
 fi
151
 
152
@@ -1307,6 +1313,10 @@
153 102 dgisselq
   vax-*-*)
154
     noconfigdirs="$noconfigdirs target-newlib target-libgloss"
155
     ;;
156
+  zip*)
157 202 dgisselq
+    noconfigdirs="$noconfigdirs target-libffi target-boehm-gc gdb gprof ${libgcj}"
158
+    unsupported_languages="$unsupported_languages fortran"
159 102 dgisselq
+    ;;
160
 esac
161
 
162
 # If we aren't building newlib, then don't build libgloss, since libgloss
163 202 dgisselq
diff -Naur '--exclude=*.swp' gcc-6.2.0/gcc/cfgexpand.c gcc-6.2.0-zip/gcc/cfgexpand.c
164
--- gcc-6.2.0/gcc/cfgexpand.c   2016-04-27 08:23:50.000000000 -0400
165 209 dgisselq
+++ gcc-6.2.0-zip/gcc/cfgexpand.c       2018-06-05 21:18:19.438798488 -0400
166
@@ -74,6 +74,16 @@
167 117 dgisselq
 #include "tree-chkp.h"
168
 #include "rtl-chkp.h"
169
 
170 202 dgisselq
+
171 209 dgisselq
+// #define     DO_ZIP_DEBUGS
172 117 dgisselq
+#ifdef DO_ZIP_DEBUGS
173
+#include <stdio.h>
174 202 dgisselq
+#define        ZIP_DEBUG_LINE(STR,RTX) do{fprintf(stderr,"%s;%d/%s\n",__FILE__,__LINE__,STR); zip_debug_rtx(RTX);} while(0)
175 117 dgisselq
+extern void    zip_debug_rtx(const_rtx);
176
+#else
177
+#define        ZIP_DEBUG_LINE(STR,RTX)
178
+#endif
179
+
180
 /* Some systems use __main in a way incompatible with its use in gcc, in these
181
    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
182
    give the same symbol without quotes for an alternative entry point.  You
183 209 dgisselq
@@ -1172,7 +1182,7 @@
184 202 dgisselq
                base_align = crtl->max_used_stack_slot_alignment;
185
              else
186
                base_align = MAX (crtl->max_used_stack_slot_alignment,
187
-                                 GET_MODE_ALIGNMENT (SImode)
188
+                                 GET_MODE_ALIGNMENT (word_mode)
189
                                  << ASAN_SHADOW_SHIFT);
190
            }
191
          else
192 209 dgisselq
@@ -2225,7 +2235,7 @@
193 202 dgisselq
          data.asan_vec.safe_push (offset);
194
          /* Leave space for alignment if STRICT_ALIGNMENT.  */
195
          if (STRICT_ALIGNMENT)
196
-           alloc_stack_frame_space ((GET_MODE_ALIGNMENT (SImode)
197
+           alloc_stack_frame_space ((GET_MODE_ALIGNMENT (word_mode)
198
                                      << ASAN_SHADOW_SHIFT)
199
                                     / BITS_PER_UNIT, 1);
200 111 dgisselq
 
201 209 dgisselq
@@ -5745,7 +5755,7 @@
202 202 dgisselq
       && (last = get_last_insn ())
203
       && JUMP_P (last))
204
     {
205
-      rtx dummy = gen_reg_rtx (SImode);
206
+      rtx dummy = gen_reg_rtx (word_mode);
207
       emit_insn_after_noloc (gen_move_insn (dummy, dummy), last, NULL);
208
     }
209
 
210
diff -Naur '--exclude=*.swp' gcc-6.2.0/gcc/cgraphbuild.c gcc-6.2.0-zip/gcc/cgraphbuild.c
211
--- gcc-6.2.0/gcc/cgraphbuild.c 2016-01-04 09:30:50.000000000 -0500
212
+++ gcc-6.2.0-zip/gcc/cgraphbuild.c     2016-12-31 16:39:44.963107994 -0500
213
@@ -32,6 +32,15 @@
214
 #include "ipa-utils.h"
215
 #include "except.h"
216
 
217
+
218 111 dgisselq
+#ifdef DO_ZIP_DEBUGS
219 202 dgisselq
+#include <stdio.h>
220
+#define        ZIP_DEBUG_LINE(STR,RTX) do{fprintf(stderr,"%s;%d/%s\n",__FILE__,__LINE__,STR); zip_debug_rtx(RTX);} while(0)
221
+extern void    zip_debug_rtx(const_rtx);
222 111 dgisselq
+#else
223
+#define        ZIP_DEBUG_LINE(STR,RTX)
224
+#endif
225
+
226
 /* Context of record_reference.  */
227
 struct record_reference_ctx
228
 {
229 202 dgisselq
diff -Naur '--exclude=*.swp' gcc-6.2.0/gcc/combine.c gcc-6.2.0-zip/gcc/combine.c
230
--- gcc-6.2.0/gcc/combine.c     2016-08-08 06:06:15.000000000 -0400
231
+++ gcc-6.2.0-zip/gcc/combine.c 2017-02-03 09:25:19.676720321 -0500
232
@@ -103,6 +103,15 @@
233
 #include "rtl-iter.h"
234
 #include "print-rtl.h"
235
 
236
+#define        DO_ZIP_DEBUGS
237
+#ifdef DO_ZIP_DEBUGS
238
+#include <stdio.h>
239
+#define        ZIP_DEBUG_LINE(STR,RTX) do{fprintf(stderr,"%s:%d/%s\n",__FILE__,__LINE__,STR); zip_debug_rtx(RTX);} while(0)
240
+extern void    zip_debug_rtx(const_rtx);
241
+#else
242
+#define        ZIP_DEBUG_LINE(STR,RTX)
243
+#endif
244
+
245
 #ifndef LOAD_EXTEND_OP
246
 #define LOAD_EXTEND_OP(M) UNKNOWN
247
 #endif
248
diff -Naur '--exclude=*.swp' gcc-6.2.0/gcc/common/config/zip/zip-common.c gcc-6.2.0-zip/gcc/common/config/zip/zip-common.c
249
--- gcc-6.2.0/gcc/common/config/zip/zip-common.c        1969-12-31 19:00:00.000000000 -0500
250
+++ gcc-6.2.0-zip/gcc/common/config/zip/zip-common.c    2017-01-11 09:41:34.483106099 -0500
251 102 dgisselq
@@ -0,0 +1,52 @@
252
+////////////////////////////////////////////////////////////////////////////////
253
+//
254
+// Filename:   common/config/zip/zip-common.c
255
+//
256
+// Project:    Zip CPU backend for the GNU Compiler Collection
257
+//
258
+// Purpose:    To eliminate the frame register automatically.
259
+//
260
+// Creator:    Dan Gisselquist, Ph.D.
261
+//             Gisselquist Technology, LLC
262
+//
263
+////////////////////////////////////////////////////////////////////////////////
264
+//
265 202 dgisselq
+// Copyright (C) 2016-2017, Gisselquist Technology, LLC
266 102 dgisselq
+//
267
+// This program is free software (firmware): you can redistribute it and/or
268
+// modify it under the terms of  the GNU General Public License as published
269
+// by the Free Software Foundation, either version 3 of the License, or (at
270
+// your option) any later version.
271
+//
272
+// This program is distributed in the hope that it will be useful, but WITHOUT
273
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
274
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
275
+// for more details.
276
+//
277
+// You should have received a copy of the GNU General Public License along
278
+// with this program.  (It's in the $(ROOT)/doc directory, run make with no
279
+// target there if the PDF file isn't present.)  If not, see
280
+// <http://www.gnu.org/licenses/> for a copy.
281
+//
282
+// License:    GPL, v3, as defined and found on www.gnu.org,
283
+//             http://www.gnu.org/licenses/gpl.html
284
+//
285
+//
286
+////////////////////////////////////////////////////////////////////////////////
287
+#include "config.h"
288
+#include "system.h"
289
+#include "coretypes.h"
290
+#include "tm.h"
291
+#include "common/common-target.h"
292
+#include "common/common-target-def.h"
293
+
294
+static const struct default_options zip_option_optimization_table[] =
295
+  {
296
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
297
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
298
+  };
299
+
300
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
301
+#define        TARGET_OPTION_OPTIMIZATION_TABLE        zip_option_optimization_table
302
+
303
+struct gcc_targetm_common      targetm_common = TARGETM_COMMON_INITIALIZER;
304 209 dgisselq
diff -Naur '--exclude=*.swp' gcc-6.2.0/gcc/config/zip/genzipops gcc-6.2.0-zip/gcc/config/zip/genzipops
305
--- gcc-6.2.0/gcc/config/zip/genzipops  1969-12-31 19:00:00.000000000 -0500
306
+++ gcc-6.2.0-zip/gcc/config/zip/genzipops      2018-03-22 18:33:09.823726748 -0400
307
@@ -0,0 +1,201 @@
308
+ELF>@@N@8       @@@@@@88@8@@@99 >>`>` (>(>`(>`TT@T@DDPtd66@6@QtdRtd>>`>`/lib64/ld-linux-x86-64.so.2GNU GNUF3m+Z\L=<94B;#tm^ fWPI@`libc.so.6exitsprintffopenputs__stack_chk_failunlinkstrlenfclosestderrfwriterenamefprintfaccessstrcmp__libc_start_main__gmon_start__GLIBC_2.4GLIBC_2.2.5ii
ui      ?`        @`@` @`(@`0@`8@`@@`H@`P@`X@`
309
+`@`h@`p@`
x@`@`HH9 HtH59 %9 @%9 h%8 h%8 h%8 h%8 h%8 h%8 h%8 hp%8 h`%8 h     P%8 h
310
+@%8 h0%8 h %8 h
%8 f1I^HHPTI@H@H>@7fD@`UH-@`HHvHt]@`f]@f.@`UH@`HHHH?HHtHt]@`]fD=8 uUHn]7 @ >`H?uHtUH]zUHHH}HEH@UHHH}HuHUHE @HǸ6UHH0H}HuHUHMLELMH}HuHMHUHEHuuuII @HǸH UHHHhH`HXHPLHL@HEH8dH%(HE1H8Hp!@HǸH8Hh!@HǸDH8HPHXH`HhH`II!@HǸHH8HPH@H`HhH`II"@HǸHH8HPH@H`HhHh?#@A<#@IHBHH8HPH@H`HhHhD#@AA#@IHHH8HPH@H`HhHhJ#@AG#@IHHH8HPH@H`HhHhP#@AM#@IHHH8HPH@H`HhHhW#@AS#@IH>HH8HPH@H`HhHh]#@AY#@IHHHEdH3%(tUHHHHHHLdH%(HE1HH`#@HǸHH$@HǸHH8$@HǸLHHHHHHMIHcHHH$@HǸRHH%@HǸ2HH%@HǸHH&@HǸLHHHHHHMIHHHEdH3%(t'UHH H}HuHUHMH}HuHMHUHEHuuuII&@HǸH UHH H}HuHUHMH}HuHMHUHEII(@HǸUHH H}HuHUHMH}HuHMHUHEII`)@HǸrUHH H}HuHUHMH}HuHMHUHEII*@HǸ+UHH H}HuHUHMH}HuHMHUHEII+@HǸUHH H}HuHUHMH}HuHMHUHEII,@HǸUHH H}HuHUHMH}HuHMHUHEII(.@HǸVUHp/@]UHAUATSH(}HuH?0 /@H:HEH/0 HEЃ}~!HEHH<-u4}HEHHHHH/ HuH9r~H/ HEHL HEHHHKIH/ H9I)LLHHUu/HEHHHYuHEHHHHEH@HEHEHHEA/@/@/@/@HHEA/@/@/@/@HHEA/@/@/@/@HHEA/@/@0@0@HHEA0@/@0@0@H`HEA$0@/@(0@/0@H?HEA60@/@90@@0@HHEAG0@/@K0@R0@HHEAY0@/@]0@i0@HHEAq0@/@u0@0@HHEA0@/@0@0@HHEHh3@A0@Ax1@
311
+2@2@3@HHHEHh5@A 3@A3@
312
+2@4@5@HxHHEؾ5@HHEع?#@<#@5@HHEعD#@A#@5@HHEعJ#@G#@5@HHEعP#@M#@5@HuHEعW#@S#@5@HZHEع]#@Y#@5@H?HEؾ5@H#HEع?#@<#@5@HkHEعD#@A#@5@HPHEعJ#@G#@5@H5HEعP#@M#@5@HHEعW#@S#@5@HHEع]#@Y#@5@HHEؾ5@HpHEع?#@<#@6@HFHEعD#@A#@6@H+HEعJ#@G#@6@HHEعP#@M#@6@HHEعW#@S#@6@HHEع]#@Y#@6@HHEؾ6@HHEع?#@<#@"6@HLHEعD#@A#@"6@H1HEعJ#@G#@"6@HHEعP#@M#@"6@HHEعW#@S#@"6@HHEع]#@Y#@"6@HHEؾ'6@H
313
+HEع?#@<#@D6@H'HEعD#@A#@D6@HHEعJ#@G#@D6@HHEعP#@M#@D6@HHEعW#@S#@D6@HHEع]#@Y#@D6@HHEؾI6@HWHEع?#@<#@f6@HHEعD#@A#@f6@HHEعJ#@G#@f6@HHEعP#@M#@f6@HjHEعW#@S#@f6@HOHEع]#@Y#@f6@H4HEؾk6@HHEع?#@<#@6@HOHEعD#@A#@6@H4HEعJ#@G#@6@HHEعP#@M#@6@HHEعW#@S#@6@HHEع]#@Y#@6@HHEHHg( HUHHpt.H
M( Hn( HUо6@HǸ^T@AWAVAAUATL%~% UH-~% SIIL)HH'Ht 1LLDAHH9uH[]A\A]A^A_Ðf.HH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
314
+;;
315
+;; Filename:   zip-ops.md
316
+;;
317
+;; Project:    Zip CPU -- a small, lightweight, RISC CPU soft core
318
+;;
319
+;; Purpose:    This is a computer generated machine description of the
320
+;;             ZipCPU's operations.  It is computer generated simply for
321
+;;     two reasons.  First, I can't seem to find a way to generate this
322
+;;     information within GCC's current constructs.  Specifically, the
323
+;;     CPU's instructions normally set the condition codes, unless they
324
+;;     are conditional instructions when they don't.  Second, the ZipCPU is
325
+;;     actually quite regular.  Almost all of the instructions have the same
326
+;;     form.  This form turns into many, many RTL instructions.  Because the
327
+;;     CPU doesn't match any of the others within GCC, that means either
328
+;;     I have a *lot* of cut, copy, paste, and edit to do to create the file
329
+;;     and upon any and every edit, or I need to build a program to generate
330
+;;     the remaining .md constructs.  Hence, I chose the latter to minimize
331
+;;     the amount of work I needed to do.
332
+;;
333
+;;
334
+;; Creator:    Dan Gisselquist, Ph.D.
335
+;;             Gisselquist Technology, LLC
336
+;;
337
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
338
+;;
339
+;; Copyright (C) 2017, Gisselquist Technology, LLC
340
+;;
341
+;; This program is free software (firmware): you can redistribute it and/or
342
+;; modify it under the terms of  the GNU General Public License as published
343
+;; by the Free Software Foundation, either version 3 of the License, or (at
344
+;; your option) any later version.
345
+;;
346
+;; This program is distributed in the hope that it will be useful, but WITHOUT
347
+;; ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
348
+;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
349
+;; for more details.
350
+;;
351
+;; License:    GPL, v3, as defined and found on www.gnu.org,
352
+;;             http://www.gnu.org/licenses/gpl.html
353
+;;
354
+;;
355
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
356
+;;
357
+;;
358
+;
359
+;
360
+; %s
361
+;
362
+;
363
+(define_insn "%s_%s"
364
+       [(cond_exec (%s (reg:CC CC_REG) (const_int 0))
365
+                       %s)]
366
+       "%s"    ; Condition
367
+       "%s.%s\t%%1,%%0 ; genzip, conditional operator" ; Template
368
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unchanged")])
369
+;
370
+;
371
+%s (genzipop_long);
372
+;
373
+;
374
+; %s (genzipop_long)
375
+;
376
+;
377
+;
378
+(define_insn "%s"
379
+       [%s
380
+       (clobber (reg:CC CC_REG))]
381
+       "%s"
382
+       "%s\t%%2,%%0    ; %s"
383
+       [(set_attr "predicable" "no") (set_attr "ccresult" "set")])
384
+;
385
+;
386
+(define_insn "%s_raw"
387
+       [%s
388
+       (set (reg:CC CC_REG) (compare:CC (match_dup 0) (const_int 0)))]
389
+       "%s"
390
+       "%s\t%%1,%%0    ; %s_raw"
391
+       [(set_attr "predicable" "no") (set_attr "ccresult" "set")])
392
+;
393
+;
394
+eqZneNZltLTgeGEltuCgeuNC(set (match_operand:SI 0 "register_operand" "=r")
395
+               (%s (match_operand:SI 1 "register_operand" "0")
396
+                       (match_operand:SI 2 "zip_opb_single_operand_p" "rO")))(set (match_dup 0) (%s (match_dup 0) (match_dup 2)))(set (match_operand:SI 0 "register_operand" "=r")
397
+               (%s (match_dup 0)
398
+                       (match_operand:SI 1 "zip_opb_single_operand_p" "rO")))(set (match_operand:SI 0 "register_operand" "=r")
399
+               (%s (match_operand:SI 1 "register_operand" "0")
400
+                       (plus:SI (match_operand:SI 2 "register_operand" "r")
401
+                               (match_operand:SI 3 "const_int_operand" "N"))))(set (match_dup 0) (%s (match_dup 0)
402
+                       (plus:SI (match_dup 2) (match_dup 3))))(set (match_operand:SI 0 "register_operand" "=r")
403
+               (%s (match_dup 0)
404
+                       (plus:SI (match_operand:SI 1 "register_operand" "r")
405
+                               (match_operand:SI 2 "const_int_operand" "N"))))%s_off;
406
+;
407
+(define_insn "%s_%s"
408
+       [(set (match_operand:SI 0 "register_operand" "=r,r,r,Q")
409
+               (if_then_else:SI (%s (reg:CC CC_REG) (const_int 0))
410
+                       (match_operand:SI 1 "general_operand" "r,Q,i,r")
411
+                       (match_dup 0)))]
412
+       ""
413
+       "@
414
+       MOV.%s  %%1,%%0 ; cmov
415
+       LW.%s   %%1,%%0 ; cmov
416
+       LDI.%s  %%1,%%0 ; cmov
417
+       SW.%s   %%1,%%0 ; cmov"
418
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unchanged")])
419
+;
420
+;
421
+(define_insn "%s_%s"
422
+       [(set (match_operand:SI 0 "register_operand" "=r")
423
+               (if_then_else:SI (%s (reg:CC CC_REG) (const_int 0))
424
+                       (plus:SI (match_dup 0)
425
+                               (match_operand:SI 1 "zip_opb_single_operand_p" "rO"))
426
+                       (match_dup 0)))]
427
+       ""
428
+       "ADD.%s %%1,%%0 ; cadd"
429
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unchanged")])
430
+;
431
+;
432
+(define_insn "%s_%s"
433
+       [(set (match_operand:SI 0 "register_operand" "=r")
434
+               (if_then_else:SI (%s (reg:CC CC_REG) (const_int 0))
435
+                       (xor:SI (match_dup 0)
436
+                               (const_int -1))
437
+                       (match_dup 0)))]
438
+       ""
439
+       "NOT.%s %%0     ; cnot"
440
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unchanged")])
441
+;
442
+;
443
+(define_insn "%s_%s"
444
+       [(set (match_operand:SI 0 "register_operand" "+r")
445
+               (if_then_else:SI (%s (reg:CC CC_REG) (const_int 0))
446
+                       (neg:SI (match_dup 0))
447
+                       (match_dup 0)))]
448
+       ""
449
+       "NEG.%s %%0     ; cneg"
450
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unchanged")])
451
+;
452
+;
453
+(define_insn "%s_%s"
454
+       [(set (match_operand:SI 0 "register_operand" "+r")
455
+               (if_then_else:SI (%s (reg:CC CC_REG) (const_int 0))
456
+                       (and:SI (match_dup 0) (match_operand:SI 1 "zip_opb_single_operand_p" "rO"))
457
+                       (match_dup 0)))]
458
+       ""
459
+       "AND.%s %%1,%%0 ; cand"
460
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unchanged")])
461
+;
462
+;
463
+(define_insn "%s_%s"
464
+       [(set (match_operand:SI 0 "register_operand" "+r")
465
+               (if_then_else:SI (%s (reg:CC CC_REG) (const_int 0))
466
+                       (ior:SI (match_dup 0) (match_operand:SI 1 "zip_opb_single_operand_p" "rO"))
467
+                       (match_dup 0)))]
468
+       ""
469
+       "OR.%s  %%1,%%0 ; cior"
470
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unchanged")])
471
+;
472
+;
473
+(define_insn "%s_%s"
474
+       [(set (match_operand:SI 0 "register_operand" "+r")
475
+               (if_then_else:SI (%s (reg:CC CC_REG) (const_int 0))
476
+                       (xor:SI (match_dup 0) (match_operand:SI 1 "zip_opb_single_operand_p" "rO"))
477
+                       (match_dup 0)))]
478
+       ""
479
+       "XOR.%s %%1,%%0 ; cxor"
480
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unchanged")])
481
+USAGE: genzipops <new-zip-ops.md filename>.zip-ops.mdzip-ops.mdwADDplus:SIaddsi3SUBminus:SIsubsi3MPYmult:SImulsi3DIVS(ZIP_DIVIDE)div:SIdivsi3DIVUudiv:SIudivsi3ANDand:SIandsi3ORior:SIiorsi3XORxor:SIxorsi3ASRashiftrt:SIashrsi3LSLashift:SIashlsi3LSRlshiftrt:SIlshrsi3(set (match_operand:SI 0 "register_operand" "=r")
482
+               (truncate:SI (ashiftrt:DI (mult:DI
483
+                       (sign_extend:DI (match_dup 0))
484
+                       (sign_extend:DI (match_operand:SI 1 "zip_opb_operand_p" "rO")))
485
+                       (const_int 32))))(set (match_dup 0)
486
+               (truncate:SI (ashiftrt:DI (mult:DI
487
+                       (sign_extend:DI (match_dup 1))
488
+                       (sign_extend:DI (match_dup 2)))
489
+                       (const_int 32))))(ZIP_HAS_DI)(set (match_operand:SI 0 "register_operand" "=r")
490
+               (truncate:SI (ashiftrt:DI (mult:DI
491
+                       (sign_extend:DI (match_operand:SI 1 "register_operand" "0"))
492
+                       (sign_extend:DI (match_operand:SI 2 "zip_opb_operand_p" "rO")))
493
+                       (const_int 32))))smulsi_highpartMPYSHI(set (match_operand:SI 0 "register_operand" "=r")
494
+               (truncate:SI (ashiftrt:DI (mult:DI
495
+                       (zero_extend:DI (match_dup 0))
496
+                       (zero_extend:DI (match_operand:SI 1 "zip_opb_operand_p" "rO")))
497
+                       (const_int 32))))(set (match_dup 0)
498
+               (truncate:SI (ashiftrt:DI (mult:DI
499
+                       (zero_extend:DI (match_dup 1))
500
+                       (zero_extend:DI (match_dup 2)))
501
+                       (const_int 32))))(set (match_operand:SI 0 "register_operand" "=r")
502
+               (truncate:SI (ashiftrt:DI (mult:DI
503
+                       (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
504
+                       (zero_extend:DI (match_operand:SI 2 "zip_opb_operand_p" "rO")))
505
+                       (const_int 32))))umulsi_highpartMPYUHIConditional move instructionscmovConditional add instructionscaddConditional negate instructionscnegConditional not instructionscnotConditional and instructionscandConditional ior instructionsciorConditional xor instructionscxorERR: Could not create %s, leaving results in %s
506
+;<<2\,LlgM,L"liz,zRx*zRx$PFJw?;*3$"D*AC
ed(-AC
h5`AC
[uAC
AC
XAC
SGAC
B$GAC
BD9GAC
Bd`GAC
BGAC
BGAC
BAC
L>AC
IDeBBE B(H0H8M@r8A0A(B BBBL@@@
@>`>`o@X@@
507
+@`P@X@0        o(@oo@(>`@&@6@F@V@f@v@@@@@@@@/@/@GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 201606098@T@t@@@X@@(@   X@
508
+@@@
@@@@6@`7@>`>` >`(>`?`@`@`@` >`0@p@.@D@`S>`z@>`9@ >`>`(>`>`6@@`!@1@G9M - @`i+@Xq@`k@M     @`@`@`+@ @@G+@`8LX@GTi x@`@@e@`  @-1@*@G@G@`>@>-@ &@*,ASg@`s @G@@`crtstuff.c__JCR_LIST__deregister_tm_clones__do_global_dtors_auxcompleted.7594__do_global_dtors_aux_fini_array_entryframe_dummy__frame_dummy_init_array_entrygenzipops.c__FRAME_END____JCR_END____init_array_end_DYNAMIC__init_array_start__GNU_EH_FRAME_HDR_GLOBAL_OFFSET_TABLE___libc_csu_finigenciorunlink@@GLIBC_2.2.5_ITM_deregisterTMCloneTablegencmovputs@@GLIBC_2.2.5TAILPATHgenzipopgenzip_condopTMPPATH_edatafclose@@GLIBC_2.2.5strlen@@GLIBC_2.2.5__stack_chk_fail@@GLIBC_2.4genzipop_longgencnot__libc_start_main@@GLIBC_2.2.5__data_startstrcmp@@GLIBC_2.2.5gencandfprintf@@GLIBC_2.2.5__gmon_start____dso_handle_IO_stdin_used__libc_csu_initgen_headinggencxorgencadd__bss_startmainusageaccess@@GLIBC_2.2.5fopen@@GLIBC_2.2.5_Jv_RegisterClassesrename@@GLIBC_2.2.5legalsprintf@@GLIBC_2.2.5exit@@GLIBC_2.2.5fwrite@@GLIBC_2.2.5__TMC_END___ITM_registerTMCloneTablegencnegstderr@@GLIBC_2.2.5.symtab.strtab.shstrtab.interp.note.ABI-tag.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rela.dyn.rela.plt.init.plt.got.text.fini.rodata.eh_frame_hdr.eh_frame.init_array.fini_array.jcr.dynamic.got.plt.data.bss.comment8@8#T@T 1t@t$Do@$N@VX@X^o@"ko(@(0zX@X0B@P@@@@@  @6@6`7@`7>`>>`> >` >(>`(>?`?@`@@`@ @`@ 0@4qM@/ I
509
\ No newline at end of file
510
diff -Naur '--exclude=*.swp' gcc-6.2.0/gcc/config/zip/genzipops.c gcc-6.2.0-zip/gcc/config/zip/genzipops.c
511
--- gcc-6.2.0/gcc/config/zip/genzipops.c        1969-12-31 19:00:00.000000000 -0500
512
+++ gcc-6.2.0-zip/gcc/config/zip/genzipops.c    2017-03-07 12:03:59.062584503 -0500
513
@@ -0,0 +1,444 @@
514
+////////////////////////////////////////////////////////////////////////////////
515
+//
516
+// Filename:   genzipops.c
517
+//
518
+// Project:    Zip CPU -- a small, lightweight, RISC CPU soft core
519
+//
520
+// Purpose:    This program generates the zip-ops.md machine description file.
521
+//
522
+//     While I understand that this is not GCC's preferred method of generating
523
+//     machine description files, there were just so many instructions to
524
+//     generate, and so many forms of them, and the GCC infrastructure didn't
525
+//     support the conditional execution model of the ZipCPU that ... I built
526
+//     it this way.
527
+//
528
+//     As of this writing, building zip-ops.md is not an automatic part of
529
+//     making GCC.  To build genzipops, just type:
530 202 dgisselq
+//
531
+//     g++ genzipops.c -o genzipops
532
+//
533
+//     And to run it, type:
534 102 dgisselq
+//
535
+//     genzipops > zip-ops.md
536 202 dgisselq
+//
537 102 dgisselq
+//     genzipops takes no arguments, and does nothing but write the machine
538 202 dgisselq
+//     descriptions to the standard output.
539 102 dgisselq
+//
540 202 dgisselq
+//
541 102 dgisselq
+// Creator:    Dan Gisselquist, Ph.D.
542 202 dgisselq
+//             Gisselquist Technology, LLC
543
+//
544
+////////////////////////////////////////////////////////////////////////////////
545
+//
546
+// Copyright (C) 2017, Gisselquist Technology, LLC
547
+//
548
+// This program is free software (firmware): you can redistribute it and/or
549
+// modify it under the terms of  the GNU General Public License as published
550
+// by the Free Software Foundation, either version 3 of the License, or (at
551
+// your option) any later version.
552
+//
553
+// This program is distributed in the hope that it will be useful, but WITHOUT
554
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
555
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
556
+// for more details.
557
+//
558
+// You should have received a copy of the GNU General Public License along
559
+// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
560
+// target there if the PDF file isn't present.)  If not, see
561 102 dgisselq
+// <http://www.gnu.org/licenses/> for a copy.
562
+//
563
+// License:    GPL, v3, as defined and found on www.gnu.org,
564
+//             http://www.gnu.org/licenses/gpl.html
565
+//
566 202 dgisselq
+//
567 102 dgisselq
+////////////////////////////////////////////////////////////////////////////////
568
+//
569
+//
570
+#include <unistd.h>
571
+#include <stdlib.h>
572
+#include <stdio.h>
573
+#include <string.h>
574
+
575
+void   legal(FILE *fp) {
576
+       fprintf(fp, ""
577
+";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
578
+";;\n"
579 202 dgisselq
+";; Filename:  zip-ops.md\n"
580 102 dgisselq
+";;\n"
581
+";; Project:   Zip CPU -- a small, lightweight, RISC CPU soft core\n"
582
+";;\n"
583
+";; Purpose:   This is a computer generated machine description of the\n"
584
+";;            ZipCPU\'s operations.  It is computer generated simply for\n"
585
+";;    two reasons.  First, I can\'t seem to find a way to generate this\n"
586
+";;    information within GCC\'s current constructs.  Specifically, the\n"
587
+";;    CPU\'s instructions normally set the condition codes, unless they\n"
588 202 dgisselq
+";;    are conditional instructions when they don\'t.  Second, the ZipCPU is\n"
589
+";;    actually quite regular.  Almost all of the instructions have the same\n"
590
+";;    form.  This form turns into many, many RTL instructions.  Because the\n"
591
+";;    CPU doesn\'t match any of the others within GCC, that means either\n"
592
+";;    I have a *lot* of cut, copy, paste, and edit to do to create the file\n"
593
+";;    and upon any and every edit, or I need to build a program to generate\n"
594 102 dgisselq
+";;    the remaining .md constructs.  Hence, I chose the latter to minimize\n"
595 202 dgisselq
+";;    the amount of work I needed to do.\n"
596
+";;\n"
597
+";;\n"
598
+";; Creator:   Dan Gisselquist, Ph.D.\n"
599
+";;            Gisselquist Technology, LLC\n"
600
+";;\n"
601
+";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
602
+";;\n"
603
+";; Copyright (C) 2017, Gisselquist Technology, LLC\n"
604
+";;\n"
605
+";; This program is free software (firmware): you can redistribute it and/or\n"
606
+";; modify it under the terms of  the GNU General Public License as published\n"
607
+";; by the Free Software Foundation, either version 3 of the License, or (at\n"
608
+";; your option) any later version.\n"
609
+";;\n"
610
+";; This program is distributed in the hope that it will be useful, but WITHOUT\n"
611
+";; ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or\n"
612
+";; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n"
613
+";; for more details.\n"
614
+";;\n"
615
+";; License:   GPL, v3, as defined and found on www.gnu.org,\n"
616
+";;            http://www.gnu.org/licenses/gpl.html\n"
617
+";;\n"
618
+";;\n"
619
+";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
620
+";;\n"
621
+";;\n");
622
+}
623
+
624
+void   gen_heading(FILE *fp, const char *heading) {
625
+       fprintf(fp, ";\n;\n; %s\n;\n;\n", heading);
626
+}
627
+
628
+void   genzip_condop(FILE *fp, const char *md_opname,
629
+               const char *rtxstr, const char *insn_cond,
630
+               const char *zip_op,
631
+               const char *rtx_cond, const char *zip_cond) {
632
+
633
+       fprintf(fp, "(define_insn \"%s_%s\"\n"
634
+               "\t[(cond_exec (%s (reg:CC CC_REG) (const_int 0))\n"
635
+               "\t\t\t%s)]\n"
636
+               "\t\"%s\"\t; Condition\n"
637
+               "\t\"%s.%s\\t%%1,%%0\t; genzip, conditional operator\"\t; Template\n"
638
+               "\t[(set_attr \"predicable\" \"no\") "
639
+               "(set_attr \"ccresult\" \"unchanged\")])\n;\n;\n",
640
+               md_opname, rtx_cond, rtx_cond, rtxstr, insn_cond, zip_op, zip_cond);
641
+
642
+}
643 102 dgisselq
+
644 202 dgisselq
+void   genzipop_long(FILE *fp, const char *md_opname, const char *uncond_rtx, const char *insn_cond, const char *split_rtx, const char *dup_rtx, const char *zip_op) {
645
+       char    heading[128];
646
+       sprintf(heading, "%s (genzipop_long)", zip_op);
647 102 dgisselq
+       fprintf(fp, ";\n;\n;\n; %s (genzipop_long)\n;\n;\n;\n", zip_op);
648 202 dgisselq
+
649
+       fprintf(fp, "(define_insn \"%s\"\n"
650
+"\t[%s\n"
651
+"\t(clobber (reg:CC CC_REG))]\n"
652 102 dgisselq
+"\t\"%s\"\n"
653 202 dgisselq
+"\t\"%s\\t%%2,%%0\t; %s\"\n"
654
+"\t[(set_attr \"predicable\" \"no\") (set_attr \"ccresult\" \"set\")])\n;\n;\n",
655
+               md_opname, uncond_rtx, insn_cond, zip_op, md_opname);
656
+
657
+
658
+       fprintf(fp, "(define_insn \"%s_raw\"\n"
659
+"\t[%s\n"
660
+"\t(set (reg:CC CC_REG) (compare:CC (match_dup 0) (const_int 0)))]\n"
661 102 dgisselq
+"\t\"%s\"\n"
662 202 dgisselq
+"\t\"%s\\t%%1,%%0\t; %s_raw\"\n"
663 102 dgisselq
+"\t[(set_attr \"predicable\" \"no\") (set_attr \"ccresult\" \"set\")])\n;\n;\n",
664 202 dgisselq
+       md_opname, dup_rtx, insn_cond, zip_op, md_opname);
665
+
666
+       genzip_condop(fp, md_opname, dup_rtx, insn_cond, zip_op, "eq", "Z");
667
+       genzip_condop(fp, md_opname, dup_rtx, insn_cond, zip_op, "ne", "NZ");
668 102 dgisselq
+       genzip_condop(fp, md_opname, dup_rtx, insn_cond, zip_op, "lt", "LT");
669 202 dgisselq
+       genzip_condop(fp, md_opname, dup_rtx, insn_cond, zip_op, "ge", "GE");
670
+       genzip_condop(fp, md_opname, dup_rtx, insn_cond, zip_op, "ltu", "C");
671
+       genzip_condop(fp, md_opname, dup_rtx, insn_cond, zip_op, "geu", "NC");
672
+}
673
+
674
+void   genzipop(FILE *fp, const char *md_opname, const char *rtx_name, const char *insn_cond, const char *zip_op) {
675
+       char    rtxstr[512], splitstr[512], dupstr[512], altname[64];
676 102 dgisselq
+
677
+       sprintf(rtxstr,
678 202 dgisselq
+"(set (match_operand:SI 0 \"register_operand\" \"=r\")\n"
679
+"\t\t(%s (match_operand:SI 1 \"register_operand\" \"0\")\n"
680
+"\t\t\t(match_operand:SI 2 \"zip_opb_single_operand_p\" \"rO\")))", rtx_name);
681
+       sprintf(splitstr,
682
+           "(set (match_dup 0) (%s (match_dup 0) (match_dup 2)))", rtx_name);
683
+
684
+       sprintf(dupstr,
685 102 dgisselq
+"(set (match_operand:SI 0 \"register_operand\" \"=r\")\n"
686 202 dgisselq
+"\t\t(%s (match_dup 0)\n"
687
+"\t\t\t(match_operand:SI 1 \"zip_opb_single_operand_p\" \"rO\")))", rtx_name);
688
+
689
+       genzipop_long(fp, md_opname, rtxstr, insn_cond, splitstr, dupstr, zip_op);
690
+
691
+       sprintf(rtxstr,
692
+"(set (match_operand:SI 0 \"register_operand\" \"=r\")\n"
693 102 dgisselq
+"\t\t(%s (match_operand:SI 1 \"register_operand\" \"0\")\n"
694 202 dgisselq
+"\t\t\t(plus:SI (match_operand:SI 2 \"register_operand\" \"r\")\n"
695
+"\t\t\t\t(match_operand:SI 3 \"const_int_operand\" \"N\"))))", rtx_name);
696 102 dgisselq
+       sprintf(splitstr,
697 202 dgisselq
+           "(set (match_dup 0) (%s (match_dup 0)\n"
698
+"\t\t\t(plus:SI (match_dup 2) (match_dup 3))))", rtx_name);
699
+
700
+       sprintf(dupstr,
701
+"(set (match_operand:SI 0 \"register_operand\" \"=r\")\n"
702
+"\t\t(%s (match_dup 0)\n"
703 102 dgisselq
+"\t\t\t(plus:SI (match_operand:SI 1 \"register_operand\" \"r\")\n"
704 202 dgisselq
+"\t\t\t\t(match_operand:SI 2 \"const_int_operand\" \"N\"))))", rtx_name);
705
+
706
+       sprintf(altname, "%s_off", md_opname);
707
+
708 102 dgisselq
+       genzipop_long(fp, altname, rtxstr, insn_cond, splitstr, dupstr, zip_op);
709 202 dgisselq
+}
710 171 dgisselq
+
711 202 dgisselq
+void   gencmov(FILE *fp, const char *md_opname, const char *md_cond, const char *zip_cond) {
712
+       fprintf(fp, ";\n;\n"
713
+"(define_insn \"%s_%s\"\n"
714
+       "\t[(set (match_operand:SI 0 \"register_operand\" \"=r,r,r,Q\")\n"
715
+               "\t\t(if_then_else:SI (%s (reg:CC CC_REG) (const_int 0))\n"
716
+               "\t\t\t(match_operand:SI 1 \"general_operand\" \"r,Q,i,r\")\n"
717
+               "\t\t\t(match_dup 0)))]\n"
718
+       "\t\"\"\n"
719 171 dgisselq
+       "\t\"@\n"
720 202 dgisselq
+       "\tMOV.%s\t%%1,%%0\t; cmov\n"
721
+       "\tLW.%s\t%%1,%%0\t; cmov\n"
722
+       "\tLDI.%s\t%%1,%%0\t; cmov\n"
723
+       "\tSW.%s\t%%1,%%0\t; cmov\"\n"
724
+       "\t[(set_attr \"predicable\" \"no\") (set_attr \"ccresult\" \"unchanged\")])\n",
725 102 dgisselq
+       md_opname, md_cond, md_cond, zip_cond, zip_cond, zip_cond, zip_cond);
726 202 dgisselq
+
727 102 dgisselq
+}
728 202 dgisselq
+
729
+void   gencadd(FILE *fp, const char *md_opname, const char *md_cond, const char *zip_cond) {
730 102 dgisselq
+       fprintf(fp, ";\n;\n"
731 202 dgisselq
+"(define_insn \"%s_%s\"\n"
732
+       "\t[(set (match_operand:SI 0 \"register_operand\" \"=r\")\n"
733
+               "\t\t(if_then_else:SI (%s (reg:CC CC_REG) (const_int 0))\n"
734
+                       "\t\t\t(plus:SI (match_dup 0)\n"
735
+                               "\t\t\t\t(match_operand:SI 1 \"zip_opb_single_operand_p\" \"rO\"))\n"
736
+                       "\t\t\t(match_dup 0)))]\n"
737
+       "\t\"\"\n"
738
+       "\t\"ADD.%s\t%%1,%%0\t; cadd\"\n"
739
+       "\t[(set_attr \"predicable\" \"no\") (set_attr \"ccresult\" \"unchanged\")])\n",
740
+       md_opname, md_cond, md_cond, zip_cond);
741
+}
742
+
743
+void   gencnot(FILE *fp, const char *md_opname, const char *md_cond, const char *zip_cond) {
744
+       fprintf(fp, ";\n;\n"
745
+"(define_insn \"%s_%s\"\n"
746 102 dgisselq
+       "\t[(set (match_operand:SI 0 \"register_operand\" \"=r\")\n"
747 202 dgisselq
+               "\t\t(if_then_else:SI (%s (reg:CC CC_REG) (const_int 0))\n"
748
+                       "\t\t\t(xor:SI (match_dup 0)\n"
749
+                               "\t\t\t\t(const_int -1))\n"
750
+                       "\t\t\t(match_dup 0)))]\n"
751
+       "\t\"\"\n"
752
+       "\t\"NOT.%s\t%%0\t; cnot\"\n"
753
+       "\t[(set_attr \"predicable\" \"no\") (set_attr \"ccresult\" \"unchanged\")])\n",
754
+       md_opname, md_cond, md_cond, zip_cond);
755
+}
756
+
757
+void   gencneg(FILE *fp, const char *md_opname, const char *md_cond, const char *zip_cond) {
758
+       fprintf(fp, ";\n;\n"
759
+"(define_insn \"%s_%s\"\n"
760
+       "\t[(set (match_operand:SI 0 \"register_operand\" \"+r\")\n"
761
+               "\t\t(if_then_else:SI (%s (reg:CC CC_REG) (const_int 0))\n"
762
+                       "\t\t\t(neg:SI (match_dup 0))\n"
763
+                       "\t\t\t(match_dup 0)))]\n"
764
+       "\t\"\"\n"
765
+       "\t\"NEG.%s\t%%0\t; cneg\"\n"
766
+       "\t[(set_attr \"predicable\" \"no\") (set_attr \"ccresult\" \"unchanged\")])\n",
767
+       md_opname, md_cond, md_cond, zip_cond);
768
+}
769
+
770
+
771
+void   gencand(FILE *fp, const char *md_opname, const char *md_cond, const char *zip_cond) {
772
+       fprintf(fp, ";\n;\n"
773
+"(define_insn \"%s_%s\"\n"
774
+       "\t[(set (match_operand:SI 0 \"register_operand\" \"+r\")\n"
775
+               "\t\t(if_then_else:SI (%s (reg:CC CC_REG) (const_int 0))\n"
776
+                       "\t\t\t(and:SI (match_dup 0) (match_operand:SI 1 \"zip_opb_single_operand_p\" \"rO\"))\n"
777
+                       "\t\t\t(match_dup 0)))]\n"
778
+       "\t\"\"\n"
779
+       "\t\"AND.%s\t%%1,%%0\t; cand\"\n"
780
+       "\t[(set_attr \"predicable\" \"no\") (set_attr \"ccresult\" \"unchanged\")])\n",
781
+       md_opname, md_cond, md_cond, zip_cond);
782
+}
783
+
784
+
785
+void   gencior(FILE *fp, const char *md_opname, const char *md_cond, const char *zip_cond) {
786
+       fprintf(fp, ";\n;\n"
787
+"(define_insn \"%s_%s\"\n"
788
+       "\t[(set (match_operand:SI 0 \"register_operand\" \"+r\")\n"
789
+               "\t\t(if_then_else:SI (%s (reg:CC CC_REG) (const_int 0))\n"
790
+                       "\t\t\t(ior:SI (match_dup 0) (match_operand:SI 1 \"zip_opb_single_operand_p\" \"rO\"))\n"
791
+                       "\t\t\t(match_dup 0)))]\n"
792
+       "\t\"\"\n"
793
+       "\t\"OR.%s\t%%1,%%0\t; cior\"\n"
794
+       "\t[(set_attr \"predicable\" \"no\") (set_attr \"ccresult\" \"unchanged\")])\n",
795
+       md_opname, md_cond, md_cond, zip_cond);
796
+}
797
+
798
+void   gencxor(FILE *fp, const char *md_opname, const char *md_cond, const char *zip_cond) {
799
+       fprintf(fp, ";\n;\n"
800
+"(define_insn \"%s_%s\"\n"
801
+       "\t[(set (match_operand:SI 0 \"register_operand\" \"+r\")\n"
802
+               "\t\t(if_then_else:SI (%s (reg:CC CC_REG) (const_int 0))\n"
803
+                       "\t\t\t(xor:SI (match_dup 0) (match_operand:SI 1 \"zip_opb_single_operand_p\" \"rO\"))\n"
804
+                       "\t\t\t(match_dup 0)))]\n"
805
+       "\t\"\"\n"
806
+       "\t\"XOR.%s\t%%1,%%0\t; cxor\"\n"
807
+       "\t[(set_attr \"predicable\" \"no\") (set_attr \"ccresult\" \"unchanged\")])\n",
808
+       md_opname, md_cond, md_cond, zip_cond);
809
+}
810
+
811
+void   usage(void) {
812
+       printf("USAGE: genzipops <new-zip-ops.md filename>\n");
813
+}
814
+
815
+const  char    *TMPPATH = ".zip-ops.md";
816
+const  char    *TAILPATH = "zip-ops.md";
817
+
818
+int main(int argc, char **argv) {
819
+       FILE    *fp = fopen(TMPPATH, "w");
820
+       const char      *newname = TAILPATH;
821
+
822
+       if ((argc>1)&&(argv[1][0] == '-')) {
823
+               usage();
824
+               exit(EXIT_FAILURE);
825
+       }
826
+
827
+       if (argc>1) {
828
+               if ((strlen(argv[1])>=strlen(TAILPATH))
829
+                       &&(strcmp(&argv[1][strlen(argv[1])-strlen(TAILPATH)],
830
+                               TAILPATH)==0)
831
+                       &&(access(argv[1], F_OK)==0))
832
+                               unlink(argv[1]);
833
+               newname = argv[1];
834
+       }
835
+
836
+       legal(fp);
837
+       genzipop(fp, "addsi3",  "plus:SI",    "",             "ADD");
838
+       genzipop(fp, "subsi3",  "minus:SI",   "",             "SUB");
839
+       genzipop(fp, "mulsi3",  "mult:SI",    "",             "MPY");
840
+       genzipop(fp, "divsi3",  "div:SI",     "(ZIP_DIVIDE)", "DIVS");
841
+       genzipop(fp, "udivsi3", "udiv:SI",    "(ZIP_DIVIDE)", "DIVU");
842
+       genzipop(fp, "andsi3",  "and:SI",     "",             "AND");
843
+       genzipop(fp, "iorsi3",  "ior:SI",     "",             "OR");
844
+       genzipop(fp, "xorsi3",  "xor:SI",     "",             "XOR");
845
+       genzipop(fp, "ashrsi3", "ashiftrt:SI","",             "ASR");
846
+       genzipop(fp, "ashlsi3", "ashift:SI",  "",             "LSL");
847
+       genzipop(fp, "lshrsi3", "lshiftrt:SI","",             "LSR");
848
+
849
+       genzipop_long(fp, "smulsi_highpart",
850
+               "(set (match_operand:SI 0 \"register_operand\" \"=r\")\n"
851
+               "\t\t(truncate:SI (ashiftrt:DI (mult:DI\n"
852
+               "\t\t\t(sign_extend:DI (match_operand:SI 1 \"register_operand\" \"0\"))\n"
853
+               "\t\t\t(sign_extend:DI (match_operand:SI 2 \"zip_opb_operand_p\" \"rO\")))\n"
854
+               "\t\t\t(const_int 32))))",
855
+               "(ZIP_HAS_DI)",
856
+               "(set (match_dup 0)\n"
857
+               "\t\t(truncate:SI (ashiftrt:DI (mult:DI\n"
858
+               "\t\t\t(sign_extend:DI (match_dup 1))\n"
859
+               "\t\t\t(sign_extend:DI (match_dup 2)))\n"
860
+               "\t\t\t(const_int 32))))",
861
+               //
862
+               "(set (match_operand:SI 0 \"register_operand\" \"=r\")\n"
863
+               "\t\t(truncate:SI (ashiftrt:DI (mult:DI\n"
864
+               "\t\t\t(sign_extend:DI (match_dup 0))\n"
865
+               "\t\t\t(sign_extend:DI (match_operand:SI 1 \"zip_opb_operand_p\" \"rO\")))\n"
866
+               "\t\t\t(const_int 32))))",
867
+               "MPYSHI");
868
+       genzipop_long(fp, "umulsi_highpart",
869
+               "(set (match_operand:SI 0 \"register_operand\" \"=r\")\n"
870
+               "\t\t(truncate:SI (ashiftrt:DI (mult:DI\n"
871
+               "\t\t\t(zero_extend:DI (match_operand:SI 1 \"register_operand\" \"0\"))\n"
872
+               "\t\t\t(zero_extend:DI (match_operand:SI 2 \"zip_opb_operand_p\" \"rO\")))\n"
873
+               "\t\t\t(const_int 32))))",
874
+               "(ZIP_HAS_DI)",
875
+               "(set (match_dup 0)\n"
876
+               "\t\t(truncate:SI (ashiftrt:DI (mult:DI\n"
877
+               "\t\t\t(zero_extend:DI (match_dup 1))\n"
878
+               "\t\t\t(zero_extend:DI (match_dup 2)))\n"
879
+               "\t\t\t(const_int 32))))",
880
+               //
881
+               "(set (match_operand:SI 0 \"register_operand\" \"=r\")\n"
882
+               "\t\t(truncate:SI (ashiftrt:DI (mult:DI\n"
883
+               "\t\t\t(zero_extend:DI (match_dup 0))\n"
884
+               "\t\t\t(zero_extend:DI (match_operand:SI 1 \"zip_opb_operand_p\" \"rO\")))\n"
885
+               "\t\t\t(const_int 32))))",
886
+               "MPYUHI");
887
+
888
+       gen_heading(fp, "Conditional move instructions");
889
+
890
+       gencmov(fp, "cmov", "eq", "Z");
891
+       gencmov(fp, "cmov", "ne", "NZ");
892
+       gencmov(fp, "cmov", "lt", "LT");
893
+       gencmov(fp, "cmov", "ge", "GE");
894
+       gencmov(fp, "cmov", "ltu", "C");
895
+       gencmov(fp, "cmov", "geu", "NC");
896
+
897
+       gen_heading(fp, "Conditional add instructions");
898
+
899
+       gencadd(fp, "cadd", "eq", "Z");
900
+       gencadd(fp, "cadd", "ne", "NZ");
901
+       gencadd(fp, "cadd", "lt", "LT");
902
+       gencadd(fp, "cadd", "ge", "GE");
903
+       gencadd(fp, "cadd", "ltu", "C");
904
+       gencadd(fp, "cadd", "geu", "NC");
905
+
906
+       gen_heading(fp, "Conditional negate instructions");
907
+
908
+       gencneg(fp, "cneg", "eq", "Z");
909
+       gencneg(fp, "cneg", "ne", "NZ");
910
+       gencneg(fp, "cneg", "lt", "LT");
911
+       gencneg(fp, "cneg", "ge", "GE");
912
+       gencneg(fp, "cneg", "ltu", "C");
913
+       gencneg(fp, "cneg", "geu", "NC");
914
+
915
+       gen_heading(fp, "Conditional not instructions");
916
+
917
+       gencnot(fp, "cnot", "eq", "Z");
918
+       gencnot(fp, "cnot", "ne", "NZ");
919
+       gencnot(fp, "cnot", "lt", "LT");
920
+       gencnot(fp, "cnot", "ge", "GE");
921
+       gencnot(fp, "cnot", "ltu", "C");
922
+       gencnot(fp, "cnot", "geu", "NC");
923
+
924
+       gen_heading(fp, "Conditional and instructions");
925
+
926
+       gencand(fp, "cand", "eq", "Z");
927
+       gencand(fp, "cand", "ne", "NZ");
928
+       gencand(fp, "cand", "lt", "LT");
929
+       gencand(fp, "cand", "ge", "GE");
930
+       gencand(fp, "cand", "ltu", "C");
931
+       gencand(fp, "cand", "geu", "NC");
932
+
933
+       gen_heading(fp, "Conditional ior instructions");
934
+
935
+       gencior(fp, "cior", "eq", "Z");
936
+       gencior(fp, "cior", "ne", "NZ");
937
+       gencior(fp, "cior", "lt", "LT");
938
+       gencior(fp, "cior", "ge", "GE");
939
+       gencior(fp, "cior", "ltu", "C");
940
+       gencior(fp, "cior", "geu", "NC");
941
+
942
+       gen_heading(fp, "Conditional xor instructions");
943
+
944
+       gencxor(fp, "cxor", "eq", "Z");
945
+       gencxor(fp, "cxor", "ne", "NZ");
946
+       gencxor(fp, "cxor", "lt", "LT");
947
+       gencxor(fp, "cxor", "ge", "GE");
948
+       gencxor(fp, "cxor", "ltu", "C");
949
+       gencxor(fp, "cxor", "geu", "NC");
950
+
951
+       fclose(fp);
952
+
953
+       if (rename(TMPPATH, newname) != 0) {
954
+               fprintf(stderr, "ERR: Could not create %s, leaving results in %s\n", newname, TMPPATH);
955
+               exit(EXIT_FAILURE);
956
+       } exit(EXIT_SUCCESS);
957
+}
958
diff -Naur '--exclude=*.swp' gcc-6.2.0/gcc/config/zip/zip.c gcc-6.2.0-zip/gcc/config/zip/zip.c
959
--- gcc-6.2.0/gcc/config/zip/zip.c      1969-12-31 19:00:00.000000000 -0500
960
+++ gcc-6.2.0-zip/gcc/config/zip/zip.c  2018-06-05 21:17:24.151098201 -0400
961
@@ -0,0 +1,2711 @@
962
+////////////////////////////////////////////////////////////////////////////////
963
+//
964
+// Filename:   zip.c
965
+//
966
+// Project:    Zip CPU backend for the GNU Compiler Collection
967
+//
968
+// Purpose:
969
+//
970
+// Creator:    Dan Gisselquist, Ph.D.
971
+//             Gisselquist Technology, LLC
972
+//
973
+////////////////////////////////////////////////////////////////////////////////
974
+//
975
+// Copyright (C) 2016-2017, Gisselquist Technology, LLC
976
+//
977
+// This program is free software (firmware): you can redistribute it and/or
978
+// modify it under the terms of  the GNU General Public License as published
979
+// by the Free Software Foundation, either version 3 of the License, or (at
980 209 dgisselq
+// your option) any later version.
981
+//
982 102 dgisselq
+// This program is distributed in the hope that it will be useful, but WITHOUT
983
+// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
984
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
985
+// for more details.
986
+//
987
+// You should have received a copy of the GNU General Public License along
988
+// with this program.  (It's in the $(ROOT)/doc directory, run make with no
989
+// target there if the PDF file isn't present.)  If not, see
990
+// <http://www.gnu.org/licenses/> for a copy.
991
+//
992
+// License:    GPL, v3, as defined and found on www.gnu.org,
993
+//             http://www.gnu.org/licenses/gpl.html
994
+//
995 202 dgisselq
+//
996 102 dgisselq
+////////////////////////////////////////////////////////////////////////////////
997
+#include "config.h"
998
+#include "system.h"
999
+#include "coretypes.h"
1000
+#include "tm.h"
1001
+#include "rtl.h"
1002
+#include "dominance.h"
1003
+#include "cfg.h"
1004
+#include "cfgrtl.h"
1005
+#include "cfganal.h"
1006
+#include "lcm.h"
1007
+#include "cfgbuild.h"
1008
+#include "cfgcleanup.h"
1009
+#include "predict.h"
1010
+#include "basic-block.h"
1011
+#include "bitmap.h"
1012
+#include "df.h"
1013
+#include "hashtab.h"
1014
+#include "hash-set.h"
1015
+#include "machmode.h"
1016
+#include "symtab.h"
1017
+#include "rtlhash.h"
1018
+#include "tree.h"
1019
+#include "regs.h"
1020
+#include "hard-reg-set.h"
1021
+#include "real.h"
1022
+#include "insn-config.h"
1023
+#include "conditions.h"
1024
+#include "output.h"
1025
+#include "insn-attr.h"
1026
+#include "flags.h"
1027
+#include "expr.h"
1028
+#include "function.h"
1029
+#include "recog.h"
1030
+#include "toplev.h"
1031 202 dgisselq
+#include "ggc.h"
1032 102 dgisselq
+#include "builtins.h"
1033
+#include "calls.h"
1034
+#include "langhooks.h"
1035
+#include "optabs.h"
1036
+#include "explow.h"
1037
+#include "emit-rtl.h"
1038
+#include "ifcvt.h"
1039
+#include "genrtl.h"
1040
+
1041
+// #include "tmp_p.h"
1042
+#include "target.h"
1043
+#include "target-def.h"
1044
+// #include "tm-constrs.h"
1045
+#include "tm-preds.h"
1046
+
1047
+#include "diagnostic.h"
1048
+// #include "integrate.h"
1049
+
1050
+#include "zip-protos.h"
1051
+
1052
+static bool    zip_return_in_memory(const_tree, const_tree);
1053
+static bool    zip_frame_pointer_required(void);
1054
+
1055
+static void zip_function_arg_advance(cumulative_args_t ca, enum machine_mode mode,
1056
+               const_tree type, bool named);
1057
+static rtx zip_function_arg(cumulative_args_t ca, enum machine_mode mode, const_tree type, bool named);
1058 122 dgisselq
+
1059 202 dgisselq
+static void    zip_asm_trampoline_template(FILE *);
1060 102 dgisselq
+static void    zip_trampoline_init(rtx, tree, rtx);
1061
+static void    zip_init_builtins(void);
1062
+static tree    zip_builtin_decl(unsigned, bool);
1063
+// static void zip_asm_output_anchor(rtx x);
1064
+       void    zip_asm_output_def(FILE *s, const char *n, const char *v);
1065 122 dgisselq
+static rtx     zip_expand_builtin(tree exp, rtx target, rtx subtarget,
1066 102 dgisselq
+                       enum machine_mode tmode, int    ignore);
1067
+static bool    zip_scalar_mode_supported_p(enum machine_mode mode);
1068
+static bool    zip_libgcc_floating_mode_supported_p(enum machine_mode mode);
1069
+static int     zip_address_cost(rtx addr, enum machine_mode mode, addr_space_t as, bool spd);
1070 200 dgisselq
+static bool    zip_mode_dependent_address_p(const_rtx addr, addr_space_t);
1071
+static unsigned HOST_WIDE_INT  zip_const_anchor = 0x20000;
1072 102 dgisselq
+static          HOST_WIDE_INT  zip_min_opb_imm = -0x20000;
1073
+static          HOST_WIDE_INT  zip_max_opb_imm =  0x1ffff;
1074
+static          HOST_WIDE_INT  zip_min_anchor_offset = -0x2000;
1075
+static          HOST_WIDE_INT  zip_max_anchor_offset =  0x1fff;
1076
+static          HOST_WIDE_INT  zip_min_mov_offset = -0x1000;
1077
+static          HOST_WIDE_INT  zip_max_mov_offset =  0x0fff;
1078
+static int     zip_sched_issue_rate(void) { return 1; }
1079
+static bool    zip_legitimate_address_p(machine_mode, rtx, bool);
1080
+static bool    zip_legitimate_move_operand_p(machine_mode, rtx, bool);
1081
+       void    zip_debug_rtx_pfx(const char *, const_rtx x);
1082 202 dgisselq
+       void    zip_debug_rtx(const_rtx x);
1083 102 dgisselq
+static void    zip_override_options(void);
1084
+static bool    zip_can_eliminate(int from ATTRIBUTE_UNUSED, int to);
1085
+static int     zip_memory_move_cost(machine_mode, reg_class_t, bool);
1086
+static rtx     zip_legitimize_address(rtx x, rtx oldx, machine_mode mode);
1087
+static bool    zip_cannot_modify_jumps_p(void);
1088
+static bool    zip_fixed_condition_code_regs(unsigned int *a, unsigned int *b);
1089
+
1090
+
1091
+#define        ZIP_ALL_DEBUG_OFF       false
1092 122 dgisselq
+#define        ZIP_ALL_DEBUG_ON        false
1093
+#define        ZIPDEBUGFLAG(A,B)       const bool A =                  \
1094 142 dgisselq
+               ((ZIP_ALL_DEBUG_ON)||(B))&&(!ZIP_ALL_DEBUG_OFF)
1095
+
1096 102 dgisselq
+enum ZIP_BUILTIN_ID_CODE {
1097
+       ZIP_BUILTIN_RTU,
1098
+       ZIP_BUILTIN_HALT,
1099
+       ZIP_BUILTIN_IDLE,
1100
+       ZIP_BUILTIN_SYSCALL,
1101
+       ZIP_BUILTIN_SAVE_CONTEXT,
1102
+       ZIP_BUILTIN_RESTORE_CONTEXT,
1103
+       ZIP_BUILTIN_BITREV,
1104
+       ZIP_BUILTIN_CC,
1105
+       ZIP_BUILTIN_UCC,
1106 111 dgisselq
+       ZIP_BUILTIN_BUSY,
1107 117 dgisselq
+       ZIP_BUILTIN_MAX
1108 122 dgisselq
+};
1109 102 dgisselq
+
1110
+static GTY (()) tree   zip_builtins[(int)ZIP_BUILTIN_MAX];
1111 202 dgisselq
+static enum insn_code  zip_builtins_icode[(int)ZIP_BUILTIN_MAX];
1112
+
1113
+#undef TARGET_ASM_ALIGNED_HI_OP
1114
+#undef TARGET_ASM_ALIGNED_SI_OP
1115 102 dgisselq
+#undef TARGET_ASM_ALIGNED_DI_OP
1116
+#define        TARGET_ASM_ALIGNED_HI_OP        "\t.short\t"
1117
+#define        TARGET_ASM_ALIGNED_SI_OP        "\t.int\t"
1118
+#define        TARGET_ASM_ALIGNED_DI_OP        "\t.quad\t"
1119
+
1120
+#undef TARGET_ASM_UNALIGNED_HI_OP
1121
+#undef TARGET_ASM_UNALIGNED_SI_OP
1122
+#undef TARGET_ASM_UNALIGNED_DI_OP
1123
+#define        TARGET_ASM_UNALIGNED_HI_OP      TARGET_ASM_ALIGNED_HI_OP
1124
+#define        TARGET_ASM_UNALIGNED_SI_OP      TARGET_ASM_ALIGNED_SI_OP
1125 117 dgisselq
+#define        TARGET_ASM_UNALIGNED_DI_OP      TARGET_ASM_ALIGNED_DI_OP
1126 171 dgisselq
+
1127 102 dgisselq
+#include "gt-zip.h"
1128
+
1129
+/* The Global 'targetm' Variable. */
1130
+struct gcc_target      targetm = TARGET_INITIALIZER;
1131
+
1132
+
1133 202 dgisselq
+enum   reg_class zip_reg_class(int);
1134
+
1135
+#define        LOSE_AND_RETURN(msgid, x)               \
1136
+       do {                                    \
1137
+               zip_operand_lossage(msgid, x);  \
1138
+               return;                         \
1139 102 dgisselq
+       } while(0)
1140 202 dgisselq
+
1141
+/* Per-function machine data. */
1142
+struct GTY(()) machine_function
1143
+{
1144
+       /* number of pretented arguments for varargs */
1145
+       int     pretend_size;
1146
+
1147 102 dgisselq
+       /* Number of bytes saved on the stack for local variables. */
1148
+       int     local_vars_size;
1149
+
1150
+       /* Number of bytes saved on stack for register save area */
1151
+       int     saved_reg_size;
1152
+       int     save_ret;
1153
+
1154
+       int     sp_fp_offset;
1155
+       bool    fp_needed;
1156
+       int     size_for_adjusting_sp;
1157
+};
1158
+
1159
+/* Allocate a chunk of memory for per-function machine-dependent data. */
1160
+
1161
+static struct machine_function *
1162
+zip_init_machine_status(void) {
1163
+       return ggc_cleared_alloc<machine_function>();
1164
+}
1165
+
1166
+static void
1167
+zip_override_options(void)
1168
+{
1169
+       init_machine_status = zip_init_machine_status;
1170
+}
1171
+
1172
+enum   reg_class
1173
+zip_reg_class(int regno)
1174
+{
1175
+       if (is_ZIP_GENERAL_REG(regno)) {
1176
+               return GENERAL_REGS;
1177
+       } else if (is_ZIP_REG(regno)) {
1178
+               return ALL_REGS;
1179
+       } return NO_REGS;
1180
+}
1181
+
1182
+/* Worker function for TARGET_RETURN_IN_MEMORY. */
1183
+static bool
1184
+zip_return_in_memory(const_tree type, const_tree fntype ATTRIBUTE_UNUSED) {
1185
+       const   HOST_WIDE_INT size = int_size_in_bytes(type);
1186
+       return (size == -1)||(size > 2*UNITS_PER_WORD);
1187
+}
1188
+
1189
+/* Emit an error emssage when we're in an asm, and a fatal error for "normal"
1190
+ * insn.  Formatted output isn't easily implemented, since we use output operand
1191
+ * lossage to output the actual message and handle the categorization of the
1192
+ * error.  */
1193
+
1194
+static void
1195
+zip_operand_lossage(const char *msgid, rtx op) {
1196
+       debug_rtx(op);
1197
+       zip_debug_rtx(op);
1198
+       output_operand_lossage("%s", msgid);
1199
+}
1200
+
1201
+/* The PRINT_OPERAND_ADDRESS worker.   */
1202
+void
1203
+zip_print_operand_address(FILE *file, rtx x) {
1204
+       ZIPDEBUGFLAG(dbg, false);
1205
+
1206 202 dgisselq
+       if (dbg) zip_debug_rtx(x);
1207 102 dgisselq
+       switch(GET_CODE(x)) {
1208
+               case REG:
1209
+                       gcc_assert(is_ZIP_REG(REGNO(x)));
1210
+                       gcc_assert(REGNO(x) < 16);
1211
+                       fprintf(file, "(%s)", reg_names[REGNO(x)]);
1212
+                       break;
1213
+               case SYMBOL_REF:
1214
+                       fprintf(file, "%s", XSTR(x,0));
1215
+                       break;
1216
+               case LABEL_REF:
1217
+                       x = LABEL_REF_LABEL(x);
1218
+               case CODE_LABEL:
1219
+                       { char buf[256];
1220
+                       ASM_GENERATE_INTERNAL_LABEL(buf, "L", CODE_LABEL_NUMBER(x));
1221
+#ifdef ASM_OUTPUT_LABEL_REF
1222
+                       ASM_OUTPUT_LABEL_REF(file, buf);
1223
+#else
1224 202 dgisselq
+                       assemble_name(file, buf);
1225 102 dgisselq
+#endif
1226
+                       }
1227
+                       break;
1228
+               case PLUS:
1229 127 dgisselq
+                       if (!REG_P(XEXP(x, 0))) {
1230 171 dgisselq
+                               fprintf(stderr, "Unsupported address construct\n");
1231 102 dgisselq
+                               zip_debug_rtx(x);
1232
+                               abort();
1233
+                       } gcc_assert(is_ZIP_REG(REGNO(XEXP(x,0))));
1234
+                       gcc_assert(REGNO(XEXP(x,0))<16);
1235
+                       if (CONST_INT_P(XEXP(x, 1))) {
1236
+                               if (INTVAL(XEXP(x,1))!=0) {
1237
+                                       fprintf(file, "%ld(%s)",
1238
+                                       (long)INTVAL(XEXP(x, 1)),
1239
+                                       reg_names[REGNO(XEXP(x, 0))]);
1240
+                               } else {
1241
+                                       fprintf(file, "(%s)",
1242
+                                       reg_names[REGNO(XEXP(x, 0))]);
1243
+                               }
1244
+                       } else if (GET_CODE(XEXP(x,1)) == SYMBOL_REF) {
1245
+                               fprintf(file, "%s(%s)", XSTR(x,0),
1246
+                                       reg_names[REGNO(XEXP(x, 0))]);
1247
+                       } else if ((GET_CODE(XEXP(x, 1)) == MINUS)
1248
+                               && (GET_CODE(XEXP(XEXP(x, 1), 0))==SYMBOL_REF)
1249 111 dgisselq
+                               && (GET_CODE(XEXP(XEXP(x, 1), 1))==SYMBOL_REF)) {
1250
+                               fprintf(file, "%s-%s(%s)",
1251
+                                       XSTR(XEXP(XEXP(x, 1),0),0),
1252 102 dgisselq
+                                       XSTR(XEXP(XEXP(x, 1),1),0),
1253 127 dgisselq
+                                       reg_names[REGNO(XEXP(x, 0))]);
1254 171 dgisselq
+                       } else
1255 127 dgisselq
+                               fprintf(file, "#INVALID(%s)",
1256 102 dgisselq
+                                       reg_names[REGNO(XEXP(x, 0))]);
1257
+                       /*
1258 135 dgisselq
+                       else if (GET_CODE(XEXP(addr, 1)) == LABEL)
1259 102 dgisselq
+                               fprintf(file, "%s(%s)",
1260
+                                       GET_CODE(XEXP(addr, 1)),
1261
+                                       reg_names[REGNO(GET_CODE(XEXP(addr, 0)))]);
1262
+                       else if ((GET_CODE(XEXP(addr, 1)) == MINUS)
1263
+                               && (GET_CODE(XEXP(GET_CODE(XEXP(addr, 1)), 0))==LABEL)
1264
+                               && (GET_CODE(XEXP(GET_CODE(XEXP(addr, 1)), 1))==LABEL)) {
1265
+                               fprintf(file, "%s-%s(%s)",
1266
+                                       reg_names[REGNO(GET_CODE(XEXP(addr, 0)))]);
1267
+                                       reg_names[REGNO(GET_CODE(XEXP(addr, 0)))]);
1268
+                                       reg_names[REGNO(GET_CODE(XEXP(addr, 0)))]);
1269
+                       }
1270
+                       */
1271
+                       break;
1272
+               // We don't support direct memory addressing within our
1273
+               // instruction set, even though the instructions themselves
1274
+               // would support direct memory addressing of the lower 18 bits
1275
+               // of memory space.
1276
+               case MEM:
1277
+                       if (dbg) zip_debug_rtx(x);
1278
+                       zip_print_operand_address(file, XEXP(x, 0));
1279
+                       break;
1280
+               case CONST_INT:
1281
+                       fprintf(file, "%ld",(long)INTVAL(x));
1282
+                       break;
1283
+               default:
1284
+                       fprintf(stderr, "Unknown address format\n");
1285
+                       zip_debug_rtx(x);
1286
+                       abort(); break;
1287
+                       // output_addr_const(file, x);
1288
+               break;
1289
+       }
1290
+}
1291
+
1292
+/* The PRINT_OPERAND worker. */
1293
+
1294
+void
1295
+zip_print_operand(FILE *file, rtx x, int code)
1296
+{
1297
+       rtx operand = x;
1298
+       int     rgoff = 0;
1299
+
1300 111 dgisselq
+       // fprintf(file, "Print Operand!\n");
1301 135 dgisselq
+
1302 111 dgisselq
+       /* New code entries should just be added to the switch below.  If
1303 102 dgisselq
+        * handling is finished, just return.  If handling was just a
1304 111 dgisselq
+        * modification of the operand, the modified operand should be put in
1305
+        * "operand", and then do a break to let default handling
1306 102 dgisselq
+        * (zero-modifier) output the operand.
1307
+        */
1308
+       switch(code) {
1309
+               case 0:
1310
+                       /* No code, print as usual. */
1311
+                       break;
1312
+               case 'L':
1313
+                       /* Lower of two registers, print one up */
1314
+                       rgoff = 1;
1315
+                       break;
1316
+               case 'R':
1317
+               case 'H':
1318
+                       /* Higher of a register pair, print normal */
1319
+                       break;
1320
+
1321
+               default:
1322
+                       LOSE_AND_RETURN("invalid operand modifier letter", x);
1323
+       }
1324
+
1325
+       /* Print an operand as without a modifier letter. */
1326
+       switch (GET_CODE(operand)) {
1327
+       case REG:
1328
+               if (REGNO(operand)+rgoff >= FIRST_PSEUDO_REGISTER)
1329
+                       internal_error("internal error: bad register: %d", REGNO(operand));
1330
+               fprintf(file, "%s", reg_names[REGNO(operand)+rgoff]);
1331
+               return;
1332
+       case SCRATCH:
1333
+               LOSE_AND_RETURN("Need a scratch register", x);
1334
+               return;
1335
+
1336
+       case CODE_LABEL:
1337
+       case LABEL_REF:
1338
+       case SYMBOL_REF:
1339
+       case PLUS:
1340
+               PRINT_OPERAND_ADDRESS(file, operand);
1341
+               return;
1342
+       case MEM:
1343
+               PRINT_OPERAND_ADDRESS(file, XEXP(operand, 0));
1344
+               return;
1345
+
1346
+       default:
1347
+               /* No need to handle all strange variants, let
1348
+                * output_addr_const do it for us.
1349
+                */
1350
+               if (CONSTANT_P(operand)) {
1351
+                       output_addr_const(file, operand);
1352
+                       return;
1353
+               }
1354
+
1355
+               zip_debug_rtx(x);
1356
+               LOSE_AND_RETURN("unexpected operand", x);
1357
+       }
1358
+}
1359
+
1360
+static bool
1361
+zip_frame_pointer_required(void)
1362
+{
1363
+       // This should really depend upon whether we have variable sized
1364
+       // arguments in our frame or not.  Once this fails, let's look
1365
+       // at what the problem was and then whether or not we can detect
1366
+       // it.
1367
+       //
1368
+       // Use a GCC global to determine our answer
1369
+       if (cfun->calls_alloca)
1370
+               return true;
1371
+
1372
+       // If the stack frame is too large to access saved registers with
1373
+       // immediate offsets, then we *must* use a frame pointer
1374
+       unsigned stack_size = 36;
1375 202 dgisselq
+       stack_size += (ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0);
1376 102 dgisselq
+
1377
+       //
1378
+       // if cfun->machine->size_for_adjusting_sp might ever be larger than
1379
+       //       zip_max_anchor_offset, then we MUST have a frame pointer.
1380
+       //
1381
+       // cfun->machine->size_for_adjusting_sp =
1382
+       //              get_frame_size
1383
+       //              + saved_reg_size (will always be <= 36)
1384
+       //              + outgoing_args_size;
1385
+       //              + pretend_args_size;
1386
+
1387
+       if(crtl->args.pretend_args_size > 0)
1388
+               stack_size += crtl->args.pretend_args_size;
1389 103 dgisselq
+       stack_size += get_frame_size();
1390
+       // Align our attempted stack size
1391 202 dgisselq
+       stack_size = ((stack_size+3)&-4);
1392
+
1393
+       // Now here's our test
1394
+       if (stack_size >= zip_max_anchor_offset)
1395
+               return true;
1396
+       return (frame_pointer_needed);
1397
+/*
1398
+*/
1399
+}
1400
+
1401
+/* Determine whether or not a register needs to be saved on the stack or not.
1402
+ */
1403
+static bool
1404
+zip_save_reg(int regno) {
1405
+       if (regno == 0)
1406
+               return ((!crtl->is_leaf)
1407
+                       ||((df_regs_ever_live_p(0))&&(!call_used_regs[0])));
1408
+       else if ((regno == zip_GOT)&&(!ZIP_PIC))
1409
+               return  ((df_regs_ever_live_p(regno))
1410
+                               &&(!call_used_regs[regno]));
1411
+       else if (regno == zip_FP)
1412
+               return((zip_frame_pointer_required())||((df_regs_ever_live_p(regno))
1413
+                               &&(!call_used_regs[regno])));
1414
+       else if (regno < zip_FP)
1415
+               return  ((df_regs_ever_live_p(regno))
1416 102 dgisselq
+                               &&(!call_used_regs[regno]));
1417
+       return false;
1418
+}
1419
+
1420
+/* Compute the size of the local area and the size to be adjusted by the
1421
+ * prologue and epilogue.
1422
+ *
1423
+ * Here's what we are looking at (top is the current, bottom is the last ...)
1424
+ *
1425
+ *     Stack Pointer ->
1426
+ *                     Outgoing arguments
1427
+ *                     Local variables (could be variable size)
1428
+ *     Frame Pointer ->        (= Stack Pointer + sp_fp_offset)
1429
+ *                     Saved return address, if saved
1430
+ *                     Other Saved registers
1431
+ *                     Saved frame pointer (if used)
1432
+ *                     Saved R12, if used
1433
+ *                     (Stack pointer is not saved)
1434
+ *                     (PRETEND-ARGS)
1435
+ *     Original stack pointer ->       (= Stack_Pointer +size_for_adjusting_sp)
1436
+ *                     Called arguments (not passed in registers)
1437
+ *                     Return arguments (not R1, args.pretend_args_size)
1438
+ *             (Prior function's stack frame ... )
1439
+ *
1440
+ */
1441
+static void
1442
+zip_compute_frame(void) {
1443
+       int     regno;
1444
+       int     args_size;
1445
+       ZIPDEBUGFLAG(dbg, false);
1446 124 dgisselq
+
1447 102 dgisselq
+       if (dbg) fprintf(stderr, "ZIP-COMPUTE-FRAME: %s\n", current_function_name());
1448
+       // gcc_assert(crtl);
1449
+       gcc_assert(cfun);
1450
+       gcc_assert(cfun->machine);
1451
+
1452
+       args_size=(ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0);
1453
+
1454 171 dgisselq
+       if(crtl->args.pretend_args_size > 0) {
1455 102 dgisselq
+               args_size += crtl->args.pretend_args_size;
1456
+               if (dbg) fprintf(stderr, "%s pretend_args_size : %d\n", current_function_name(),
1457
+                       crtl->args.pretend_args_size);
1458
+               cfun->machine->pretend_size = crtl->args.pretend_args_size;
1459
+       }
1460
+
1461
+       cfun->machine->local_vars_size = get_frame_size();
1462
+
1463
+       // Force frame alignment of the local variable section
1464
+       cfun->machine->local_vars_size += 3;
1465 202 dgisselq
+       cfun->machine->local_vars_size &= -4;
1466 102 dgisselq
+
1467 171 dgisselq
+       // Save callee-saved registers.
1468 102 dgisselq
+       cfun->machine->saved_reg_size = 0;
1469
+       for(regno=0; regno < FIRST_PSEUDO_REGISTER; regno++) {
1470
+               if (zip_save_reg(regno))
1471
+                       cfun->machine->saved_reg_size += 4;
1472
+       }
1473
+
1474
+       cfun->machine->fp_needed = (zip_frame_pointer_required());
1475
+
1476 171 dgisselq
+       if ((cfun->machine->fp_needed)&&
1477
+                       (!df_regs_ever_live_p(zip_FP))) {
1478 102 dgisselq
+               cfun->machine->saved_reg_size += 4;
1479
+       }
1480
+
1481
+       cfun->machine->sp_fp_offset = crtl->outgoing_args_size
1482
+                               + cfun->machine->local_vars_size;
1483 202 dgisselq
+       cfun->machine->size_for_adjusting_sp = cfun->machine->local_vars_size
1484
+                       + cfun->machine->saved_reg_size
1485
+                       + args_size;
1486
+       if(dbg) {
1487 102 dgisselq
+               fprintf(stderr, "\t---- STACK PTR ----\n");
1488
+               fprintf(stderr, "\tOUTGOIN-SIZE: %d\n",
1489
+                       crtl->outgoing_args_size);
1490
+               fprintf(stderr, "\tLOCALS-SIZE : %d\n",
1491 202 dgisselq
+                       cfun->machine->local_vars_size);
1492 102 dgisselq
+               fprintf(stderr, "\t---- FRAME PTR ----%s\n",
1493
+                       cfun->machine->fp_needed?"":" (Eliminated)");
1494
+               fprintf(stderr, "\tREGISTERS   : %d\n",
1495
+                       cfun->machine->saved_reg_size);
1496
+               fprintf(stderr, "\tPRETEND SIZE: %d\n",
1497
+                       crtl->args.pretend_args_size);
1498 202 dgisselq
+               fprintf(stderr, "\t---- ARG PTR (Original SP, should be eliminated) ----\n");
1499 102 dgisselq
+               fprintf(stderr, "\t----\n");
1500
+               fprintf(stderr, "\tARGS-SIZE   : %d\n", args_size);
1501 171 dgisselq
+               fprintf(stderr, "\tSP_FP_OFFSET: %d\n",
1502
+                       cfun->machine->sp_fp_offset);
1503 102 dgisselq
+               fprintf(stderr, "\tSP-ADJUSTMNT: %d\n",
1504
+                       cfun->machine->size_for_adjusting_sp);
1505
+       }
1506 124 dgisselq
+}
1507 171 dgisselq
+
1508
+void
1509
+zip_save_registers(rtx basereg_rtx, int sp_offset_to_first_register) {
1510 124 dgisselq
+       rtx     insn;
1511
+       ZIPDEBUGFLAG(dbg, false);
1512 171 dgisselq
+
1513
+       // Compute Frame has already been calculated before coming into here
1514 124 dgisselq
+       //
1515
+       // zip_compute_frame();
1516 171 dgisselq
+       if (dbg)  fprintf(stderr, "PROLOGUE::SAVE-REGISTER\n");
1517
+
1518
+       int offset = 0, regno;
1519
+       for(regno=0; regno < FIRST_PSEUDO_REGISTER; regno++) {
1520
+               if (zip_save_reg(regno)) {
1521 124 dgisselq
+                       if (dbg) fprintf(stderr,
1522
+                               "PROLOGUE::SAVE-REGISTER Saving R%d in %d+%d(SP)\n",
1523
+                               regno, sp_offset_to_first_register, offset);
1524
+                       insn=emit_insn(gen_movsi_sto_off(
1525
+                               basereg_rtx,
1526 102 dgisselq
+                               GEN_INT(sp_offset_to_first_register +offset),
1527
+                               gen_rtx_REG(SImode, regno)));
1528
+                       RTX_FRAME_RELATED_P(insn) = 1;
1529 202 dgisselq
+                       offset += 4;
1530 102 dgisselq
+               }
1531 202 dgisselq
+       } if (dbg)  fprintf(stderr, "%d registers saved%s\n", offset,
1532 102 dgisselq
+               (crtl->saves_all_registers)?", should be all of them":", less than all");
1533 202 dgisselq
+
1534
+}
1535
+
1536
+/*
1537
+ * zip_expand_small_prologue()
1538
+ *
1539
+ * To be used when the sp_fp_offset is less then zip_max_opb_offset.
1540
+ *
1541
+ *
1542
+ * Approach:
1543
+ *     SUB size_for_adjusting_sp,SP
1544
+ *     SW REG,0(SP)
1545
+ *     SW REG,4(SP)
1546
+ *     SW REG,8(SP)
1547
+ *     ....
1548
+ *     SW REG,#(SP)
1549
+ *
1550
+ * and if we need a frame register, we'll either do ...
1551
+ *     MOV sp_fp_offset+SP,FP
1552
+ * or if the offset is too large, we'll do ...
1553
+ *     MOV SP,FP
1554
+ *     ADD sp_fp_offset,FP
1555
+ *
1556
+ */
1557
+void
1558
+zip_expand_small_prologue(void) {
1559
+       ZIPDEBUGFLAG(dbg, false);
1560
+       rtx     insn;
1561
+
1562
+       zip_compute_frame();
1563
+
1564
+       if (dbg)  fprintf(stderr, "PROLOGUE:::EXPAND-SMALL-PROLOGUE(SP-FP offset is %d)\n",
1565
+               cfun->machine->sp_fp_offset);
1566
+
1567
+       insn = emit_insn(gen_subsi3(stack_pointer_rtx, stack_pointer_rtx,
1568
+                       gen_int_mode(cfun->machine->size_for_adjusting_sp,
1569
+                               SImode)));
1570
+       RTX_FRAME_RELATED_P(insn) = 1;
1571
+
1572
+       zip_save_registers(stack_pointer_rtx, cfun->machine->sp_fp_offset);
1573
+
1574
+       if (cfun->machine->fp_needed) {
1575
+               if (dbg)  fprintf(stderr, "PROLOGUE:::EXPAND-SMALL-PROLOGUE(FP-NEEDED)\n");
1576
+               if (dbg) zip_debug_rtx(stack_pointer_rtx);
1577
+               if (dbg) zip_debug_rtx(frame_pointer_rtx);
1578
+               if (cfun->machine->sp_fp_offset < zip_max_mov_offset) {
1579
+                       if (dbg)  fprintf(stderr,
1580
+                               "PROLOGUE:::EXPAND-SMALL-PROLOGUE() "
1581
+                               "gen_movsi_reg_off(FP, SP, %d), %d < %ld\n",
1582 102 dgisselq
+                               cfun->machine->sp_fp_offset,
1583
+                               cfun->machine->sp_fp_offset,
1584 202 dgisselq
+                               zip_max_mov_offset);
1585
+                       insn = emit_insn(gen_movsi_reg_off(frame_pointer_rtx,
1586
+                               stack_pointer_rtx,
1587
+                               GEN_INT(cfun->machine->sp_fp_offset)));
1588 102 dgisselq
+                       RTX_FRAME_RELATED_P(insn) = 1;
1589
+               } else {
1590 202 dgisselq
+                       rtx     fp_rtx;
1591 102 dgisselq
+
1592 202 dgisselq
+                       fp_rtx = gen_rtx_REG(SImode, zip_FP);
1593 102 dgisselq
+
1594
+                       insn = emit_insn(gen_movsi(fp_rtx, stack_pointer_rtx));
1595 202 dgisselq
+                       RTX_FRAME_RELATED_P(insn) = 1;
1596 102 dgisselq
+
1597
+                       insn = emit_insn(gen_addsi3(fp_rtx, fp_rtx,
1598 202 dgisselq
+                               GEN_INT(cfun->machine->sp_fp_offset)));
1599
+                       RTX_FRAME_RELATED_P(insn) = 1;
1600
+               }
1601
+       }
1602
+}
1603
+
1604
+/*
1605
+ * zip_expand_large_prologue()
1606 124 dgisselq
+ *
1607
+ * The prologue function will be called when the size_for_adjusting_sp is too
1608 202 dgisselq
+ * large to fit into a single OPB-immediate as part of a subtract.
1609
+ *
1610
+ * Approach:
1611
+ *     SUB (size_for_adjusting_sp-sp_fp_offset),SP
1612
+ *     SW R0,(SP)
1613
+ *     SW R5,4(SP)
1614
+ *     SW R6,8SP)
1615
+ *     SW R7,(SP)
1616
+ *     ...
1617
+ *     SW FP,(SP)
1618
+ *
1619
+ *     LDI sp_fp_offset,FP
1620
+ *     SUB FP,SP
1621 102 dgisselq
+ *     ADD SP,FP
1622
+ */
1623
+void
1624 202 dgisselq
+zip_expand_large_prologue(void) {
1625
+       ZIPDEBUGFLAG(dbg, false);
1626
+       rtx     insn, fp_rtx;
1627
+
1628
+       gcc_assert(cfun->machine->fp_needed);
1629
+
1630
+       if (dbg)        fprintf(stderr, "PROLOGUE::expand-large(%d-%d)\n",
1631
+                               cfun->machine->size_for_adjusting_sp,
1632
+                               cfun->machine->sp_fp_offset);
1633
+       insn = emit_insn(gen_subsi3(stack_pointer_rtx, stack_pointer_rtx,
1634
+               gen_int_mode(cfun->machine->size_for_adjusting_sp
1635
+                               -cfun->machine->sp_fp_offset, SImode)));
1636
+       RTX_FRAME_RELATED_P(insn) = 1;
1637
+
1638
+       zip_save_registers(stack_pointer_rtx, 0);
1639
+
1640
+       fp_rtx = gen_rtx_REG(SImode, zip_FP);
1641
+
1642
+       insn = emit_insn(gen_movsi(fp_rtx,
1643
+               gen_int_mode(cfun->machine->sp_fp_offset, SImode)));
1644
+       RTX_FRAME_RELATED_P(insn) = 1;
1645
+
1646
+       insn = emit_insn(gen_subsi3(stack_pointer_rtx, stack_pointer_rtx,
1647
+                       fp_rtx));
1648
+       RTX_FRAME_RELATED_P(insn) = 1;
1649
+
1650
+       insn = emit_insn(gen_addsi3(fp_rtx, fp_rtx, stack_pointer_rtx));
1651
+       RTX_FRAME_RELATED_P(insn) = 1;
1652
+}
1653
+
1654
+void
1655
+zip_expand_prologue(void) {
1656
+       ZIPDEBUGFLAG(dbg, false);
1657
+
1658
+       zip_compute_frame();
1659
+
1660
+       if (dbg)  fprintf(stderr, "PROLOGUE: Computing Prologue instructions\n");
1661
+       if (dbg)  fprintf(stderr, "PROLOGUE: SP-FP offset is %d\n",
1662
+                       cfun->machine->sp_fp_offset);
1663
+       if (cfun->machine->size_for_adjusting_sp != 0) {
1664
+               if (cfun->machine->size_for_adjusting_sp <= zip_max_anchor_offset) {
1665
+                       if (dbg)  fprintf(stderr, "PROLOGUE: "
1666
+                                       "%d <= %ld, so going small\n",
1667
+                                       cfun->machine->size_for_adjusting_sp,
1668
+                                       zip_max_opb_imm);
1669
+                       zip_expand_small_prologue();
1670
+               } else {
1671
+                       zip_expand_large_prologue();
1672
+               }
1673
+       }
1674
+}
1675
+
1676
+int
1677
+zip_use_return_insn(void)
1678
+{
1679
+       if ((!reload_completed)||(cfun->machine->fp_needed)
1680
+                       ||(get_frame_size()!=0)) {
1681
+               // If R0 ever gets pushed to the stack, then we cannot
1682
+               // use a master return from anywhere.  We need to clean up the
1683
+               // stack first.
1684
+               if ((!crtl->is_leaf)||((df_regs_ever_live_p(0))
1685
+                                               &&(!call_used_regs[0]))) {
1686
+                       return 0;
1687
+               }
1688
+       }
1689
+       zip_compute_frame();
1690
+       return (cfun->machine->size_for_adjusting_sp == 0)?1:0;
1691
+}
1692
+
1693
+/* As per the notes in M68k.c, quote the function epilogue should not depend
1694
+ * upon the current stack pointer.  It should use the frame pointer only,
1695
+ * if there is a frame pointer.  This is mandatory because of alloca; we also
1696 200 dgisselq
+ * take advantage of it to omit stack adjustments before returning ...
1697 102 dgisselq
+ *
1698
+ * Let's see if we can use their approach here.
1699
+ *
1700
+ * We can't.  Consider our choices:
1701
+ *     LW (FP),R0
1702
+ *     LW 4(FP),R4
1703
+ *     LW 8(FP),R5
1704
+ *     LW 12(FP),R6
1705
+ *     LW 16(FP),FP
1706 200 dgisselq
+ *     ... Then what is the stack pointer?
1707 102 dgisselq
+ * or
1708
+ *     LW (FP),R0
1709
+ *     LW 4(FP),R4
1710 200 dgisselq
+ *     LW 8(FP),R5
1711 102 dgisselq
+ *     LW 12(FP),R6
1712
+ *     MOV FP,SP
1713
+ *     LW 16(SP),FP
1714 202 dgisselq
+ *     ... Which suffers unnecessary pipeline stalls, and certainly doesn't
1715 102 dgisselq
+ *     exploit our pipeline memory function
1716
+ * or
1717
+ *     MOV FP,SP
1718
+ *     LW (SP),R0
1719
+ *     LW 4(SP),R4
1720
+ *     LW 8(SP),R5
1721 202 dgisselq
+ *     LW 12(SP),R6
1722
+ *     LW 16(SP),FP
1723
+ * Which will be our choice.  Note that we do use the stack pointer, eventually.
1724
+ *
1725
+ */
1726 102 dgisselq
+void
1727
+zip_expand_epilogue(void) {
1728 202 dgisselq
+       int     regno, offset;
1729
+       ZIPDEBUGFLAG(dbg, false);
1730
+       rtx     insn;
1731
+
1732 102 dgisselq
+       zip_compute_frame();
1733 202 dgisselq
+
1734 102 dgisselq
+       if (dbg) fprintf(stderr, "EPILOG::\n");
1735
+       if (cfun->machine->fp_needed) {
1736
+               // This is done special--if you can't trust the stack pointer
1737
+               // enough so that you must have a frame pointer, then you can't
1738 202 dgisselq
+               // trust its offset enough to restore from it.  Hence, we start
1739
+               // by moving the frame pointer to the stack pointer to recover
1740
+               // the stack pointer back to a usable value.
1741
+               if (dbg) fprintf(stderr, "EPILOG::Moving frame pointer to stack register\n");
1742
+               insn = emit_insn(gen_movsi_raw(stack_pointer_rtx, frame_pointer_rtx));
1743 102 dgisselq
+               RTX_FRAME_RELATED_P(insn) = 1;
1744
+       }
1745
+
1746
+       if (cfun->machine->saved_reg_size != 0) {
1747
+               if (cfun->machine->fp_needed)
1748
+                       offset = 0;
1749 202 dgisselq
+               else
1750 138 dgisselq
+                       offset = cfun->machine->sp_fp_offset;
1751 102 dgisselq
+               if (dbg) fprintf(stderr, "EPILOG::Saved_REG_Size = %d\n", cfun->machine->saved_reg_size);
1752
+               for(regno=0; regno < FIRST_PSEUDO_REGISTER; regno++) {
1753
+                       if (zip_save_reg(regno)) {
1754
+                               if (dbg) fprintf(stderr, "EPILOG::RESTORING R%d from SP+%d\n", regno, offset);
1755
+                               rtx reg = gen_rtx_REG(SImode, regno);
1756 124 dgisselq
+                               insn = emit_insn(gen_movsi_lod_off(
1757
+                                               reg,
1758
+                                               stack_pointer_rtx,
1759
+                                               GEN_INT(offset)));
1760
+                               add_reg_note(insn, REG_CFA_RESTORE, reg);
1761 102 dgisselq
+                               RTX_FRAME_RELATED_P(insn) = 1;
1762 202 dgisselq
+                               offset += 4;
1763 138 dgisselq
+                       }
1764 102 dgisselq
+               }
1765
+       }
1766
+
1767 124 dgisselq
+       if (cfun->machine->fp_needed) {
1768
+               // Restore the stack pointer back to the original, the
1769
+               // difference being the difference from the frame pointer
1770
+               // to the original stack
1771 102 dgisselq
+               insn = emit_insn(gen_addsi3(stack_pointer_rtx,
1772
+                       stack_pointer_rtx,
1773
+                       GEN_INT(cfun->machine->size_for_adjusting_sp
1774 202 dgisselq
+                               -cfun->machine->sp_fp_offset)));
1775 138 dgisselq
+               RTX_FRAME_RELATED_P(insn) = 1;
1776
+       } else {
1777
+               // else now the difference is between the stack pointer and
1778 124 dgisselq
+               // the original stack pointer.
1779 202 dgisselq
+               if (dbg) fprintf(stderr, "EPILOG::ADDSI3(StackPtr, %d)\n",
1780 138 dgisselq
+                               cfun->machine->size_for_adjusting_sp);
1781
+               insn = emit_insn(gen_addsi3(stack_pointer_rtx, stack_pointer_rtx,
1782 202 dgisselq
+                       GEN_INT(cfun->machine->size_for_adjusting_sp)));
1783 102 dgisselq
+               RTX_FRAME_RELATED_P(insn) = 1;
1784
+       }
1785
+       if (dbg) fprintf(stderr, "EPILOG::EMITTING-RETURN\n");
1786
+
1787 124 dgisselq
+       // The return RTX is not allowed to be frame related
1788
+       insn = emit_jump_insn(ret_rtx);
1789
+       // RTX_FRAME_RELATED_P(insn) = 1;
1790
+}
1791 202 dgisselq
+
1792 138 dgisselq
+void
1793 124 dgisselq
+zip_sibcall_epilogue(void) {
1794
+       int     regno, offset;
1795 138 dgisselq
+       ZIPDEBUGFLAG(dbg, false);
1796 124 dgisselq
+       rtx     insn;
1797
+
1798
+       zip_compute_frame();
1799 102 dgisselq
+
1800
+       if (dbg) fprintf(stderr, "EPILOG::\n");
1801 202 dgisselq
+       if (cfun->machine->fp_needed) {
1802 124 dgisselq
+               // This is done special--if you can't trust the stack pointer
1803 138 dgisselq
+               // enough so that you must have a frame pointer, then you can't
1804 102 dgisselq
+               // trust its offset enough to restore from it.  Hence, we start
1805
+               // by moving the frame pointer to the stack pointer to recover
1806
+               // the stack pointer back to a usable value.
1807 138 dgisselq
+               if (dbg) fprintf(stderr, "SIBCALL-EPILOG::Moving frame pointer to stack register\n");
1808
+               insn = emit_insn(gen_movsi_raw(stack_pointer_rtx, frame_pointer_rtx));
1809
+               RTX_FRAME_RELATED_P(insn) = 1;
1810 102 dgisselq
+       }
1811
+
1812 191 dgisselq
+       if (cfun->machine->saved_reg_size != 0) {
1813
+               if (cfun->machine->fp_needed)
1814
+                       offset = 0;
1815 202 dgisselq
+               else
1816 191 dgisselq
+                       offset = cfun->machine->sp_fp_offset;
1817
+               if (dbg) fprintf(stderr, "SIBCALL-EPILOG::Saved_REG_Size = %d\n", cfun->machine->saved_reg_size);
1818
+               for(regno=0; regno < FIRST_PSEUDO_REGISTER; regno++) {
1819
+                       if (zip_save_reg(regno)) {
1820
+                               if (dbg) fprintf(stderr, "SIBCALL-EPILOG::RESTORING R%d\n", regno);
1821
+                               rtx reg = gen_rtx_REG(SImode, regno);
1822
+                               insn = emit_insn(gen_movsi_lod_off(
1823
+                                               reg,
1824
+                                               stack_pointer_rtx,
1825
+                                               GEN_INT(offset)));
1826
+                               add_reg_note(insn, REG_CFA_RESTORE, reg);
1827
+                               RTX_FRAME_RELATED_P(insn) = 1;
1828 202 dgisselq
+                               offset += 4;
1829 191 dgisselq
+                       }
1830
+               }
1831
+       }
1832
+
1833
+       if (cfun->machine->fp_needed) {
1834
+               // Restore the stack pointer back to the original, the
1835
+               // difference being the difference from the frame pointer
1836
+               // to the original stack
1837
+               insn = emit_insn(gen_addsi3(stack_pointer_rtx, stack_pointer_rtx,
1838
+                       GEN_INT(cfun->machine->size_for_adjusting_sp
1839
+                               -cfun->machine->sp_fp_offset)));
1840
+               RTX_FRAME_RELATED_P(insn) = 1;
1841
+       } else {
1842
+               // else now the difference is between the stack pointer and
1843
+               // the original stack pointer.
1844
+               if (dbg) fprintf(stderr, "SIBCALL-EPILOG::ADDSI3(StackPtr, %d)\n",
1845 202 dgisselq
+                               cfun->machine->size_for_adjusting_sp);
1846 191 dgisselq
+               insn = emit_insn(gen_addsi3(stack_pointer_rtx,stack_pointer_rtx,
1847
+                       GEN_INT(cfun->machine->size_for_adjusting_sp)));
1848 202 dgisselq
+               RTX_FRAME_RELATED_P(insn) = 1;
1849 191 dgisselq
+       }
1850
+}
1851
+
1852
+rtx
1853
+zip_return_addr_rtx(int count, rtx frame ATTRIBUTE_UNUSED)
1854
+{
1855
+       //
1856
+       // Don't try to compute anything other than frame zero.
1857 202 dgisselq
+       //
1858 191 dgisselq
+       if (count != 0)
1859
+               return NULL_RTX;
1860
+
1861
+       // Make sure we've computed our frame, do we need to save registers?
1862
+       zip_compute_frame();
1863
+
1864
+       if (zip_save_reg(zip_LR)) {
1865
+               if (cfun->machine->fp_needed)
1866 202 dgisselq
+                       return gen_rtx_MEM(SImode, frame_pointer_rtx);
1867 191 dgisselq
+               else
1868
+                       return gen_rtx_MEM(SImode, gen_rtx_PLUS(Pmode,
1869
+                                       stack_pointer_rtx,
1870
+                                       GEN_INT(cfun->machine->sp_fp_offset)));
1871
+       } else {
1872 202 dgisselq
+               return gen_rtx_REG(Pmode, zip_LR);
1873
+
1874
+       }
1875
+}
1876
+
1877
+/* Implement RETURN_ADDR_RTX(COUNT, FRAMEADDR).
1878
+ *
1879
+ * We currently only support calculating the return address for the current
1880
+ * frame.
1881
+ */
1882
+
1883
+/*
1884
+rtx
1885
+zip_return_addr_rtx(int count, rtx frame ATTRIBUTE_UNUSED)
1886
+{
1887
+       if (count)
1888
+               return NULL_RTX;
1889
+
1890
+       zip_compute_frame();
1891
+
1892
+       // saved return address for current function is at fp - 1
1893
+       if (cfun->machine->save_ret)
1894
+               return gen_rtx_MEM(Pmode, plus_constant(frame_pointer_rtx,
1895
+                               -UNITS_PER_WORD));
1896
+       return get_hard_reg_initial_val(Pmode, RETURN_ADDRESS_REGNUM);
1897 102 dgisselq
+}
1898
+*/
1899
+
1900
+/* Implements the macro INITIAL_ELIMINATION_OFFSET,
1901
+ * return the OFFSET.
1902
+ */
1903
+int
1904
+zip_initial_elimination_offset(int from, int to) {
1905
+       int     ret = 0;
1906
+       zip_compute_frame();
1907
+
1908
+/*
1909
+       if (((from) == FRAME_POINTER_REGNUM)&&((to) == STACK_POINTER_REGNUM)) {
1910
+               ret = cfun->machine->sp_fp_offset;
1911
+       } else if (((from)=ARG_POINTER_REGNUM)&&((to)==STACK_POINTER_REGNUM)) {
1912
+               // Since the ARG_POINTER_REGNUM is defined to be identical
1913
+               // to the FRAME_POINTER_REGNUM, this "if" will never ever
1914
+               // get called.
1915
+               ret = cfun->machine->sp_fp_offset;
1916
+       } else if (((from)=ARG_POINTER_REGNUM)&&((to)==FRAME_POINTER_REGNUM)) {
1917
+               // Since we define ARG_POINTER_REGNUM to be FRAME_POINTER_REGNUM
1918
+               // we're asked for the offset between the frame pointer and
1919
+               // itself.  The result had better be zero.
1920
+               //
1921
+               ret = 0;
1922
+       } else {
1923
+               abort();
1924
+       }
1925
+*/
1926
+
1927
+       // Let's try using an ARG_POINTER != FRAME_POINTER
1928 171 dgisselq
+       if (((from) == FRAME_POINTER_REGNUM)&&((to) == STACK_POINTER_REGNUM)) {
1929 102 dgisselq
+               ret = cfun->machine->sp_fp_offset;
1930
+       } else if (((from)=ARG_POINTER_REGNUM)&&((to)==STACK_POINTER_REGNUM)) {
1931 117 dgisselq
+               // Since the ARG_POINTER_REGNUM is defined to be identical
1932 171 dgisselq
+               // to the FRAME_POINTER_REGNUM, this "if" will never ever
1933
+               // get called.
1934
+               ret = cfun->machine->size_for_adjusting_sp;
1935 117 dgisselq
+       } else if (((from)=ARG_POINTER_REGNUM)&&((to)==FRAME_POINTER_REGNUM)) {
1936 102 dgisselq
+               ret = cfun->machine->size_for_adjusting_sp
1937 171 dgisselq
+                       - cfun->machine->sp_fp_offset;
1938
+       } else {
1939
+               abort();
1940
+       }
1941 117 dgisselq
+
1942 102 dgisselq
+       return ret;
1943
+}
1944
+
1945 171 dgisselq
+/*
1946 102 dgisselq
+ * Code taken from m68k ...
1947 171 dgisselq
+ */
1948
+static bool
1949
+zip_can_eliminate(int from, int to)
1950
+{
1951
+       // fprintf(stderr, "CAN_ELIMINATE::QUERYING(%d,%d)\n", from, to);
1952
+       if ((from == zip_FP)&&(to == zip_SP))
1953
+               return !cfun->machine->fp_needed;
1954
+       return true;
1955
+}
1956
+
1957
+/* Compute the number of word sized registers needed to hold a function
1958
+ * argument of mode INT_MODE and tree type TYPE.
1959
+ */
1960
+int
1961
+zip_num_arg_regs(enum machine_mode mode, const_tree type) {
1962 102 dgisselq
+       int     size;
1963
+
1964
+       if (targetm.calls.must_pass_in_stack(mode, type))
1965
+               return 0;
1966
+
1967
+       if ((type)&&(mode == BLKmode))
1968
+               size = int_size_in_bytes(type);
1969
+       else
1970
+               size = GET_MODE_SIZE(mode);
1971
+
1972
+       return (size + UNITS_PER_WORD - 1)/UNITS_PER_WORD;
1973
+}
1974
+
1975
+static void
1976
+zip_function_arg_advance(cumulative_args_t ca, machine_mode mode,
1977 171 dgisselq
+               const_tree type, bool named ATTRIBUTE_UNUSED) {
1978 102 dgisselq
+       CUMULATIVE_ARGS *cum;
1979
+       int     nreg;
1980
+
1981
+       cum = get_cumulative_args(ca);
1982
+       nreg = zip_num_arg_regs(mode, type);
1983
+       if (((*cum)+nreg) > NUM_ARG_REGS)
1984
+               (*cum) = NUM_ARG_REGS;
1985
+       else
1986
+               (*cum) += nreg;
1987
+}
1988
+
1989
+static rtx
1990
+zip_function_arg(cumulative_args_t ca, machine_mode mode,
1991
+               const_tree type ATTRIBUTE_UNUSED, bool named) {
1992
+       CUMULATIVE_ARGS *cum;
1993
+
1994
+       if (!named)
1995
+               return NULL_RTX;
1996
+       cum = get_cumulative_args(ca);
1997
+
1998
+       if ((*cum) >= NUM_ARG_REGS)
1999
+               return NULL_RTX;
2000
+       return
2001
+               gen_rtx_REG(mode, (*cum)+1);
2002
+}
2003
+
2004
+/* DECL is the declaration of the function being targeted by the call, and EXP
2005
+ * is the CALL_EXPR representing the call.
2006
+ */
2007
+bool   zip_function_ok_for_sibcall(ATTRIBUTE_UNUSED tree decl, tree exp) {
2008
+       // calls.c already checks whether or not the parameter stack space
2009
+       // is identical, so ... let's hope this all works and find out.
2010
+
2011
+       //
2012
+       // Actually, this will fail:  If the sibling uses R5 to pass registers
2013
+       // in and we don't, then there will be no way to restore R5.  This is
2014
+       // true for the current configuration.  It will be true for future
2015
+       // configurations if the sibling ever uses a register that must be
2016
+       // saved as a parameter register.
2017
+       //
2018
+       // We can check this ... if we can count how many registers the
2019
+       // sibling call will use.
2020
+       //
2021
+       CUMULATIVE_ARGS cum_v;
2022
+       cumulative_args_t       cum;
2023
+       tree            parameter;
2024 191 dgisselq
+       machine_mode    mode;
2025
+       tree            ttype;
2026
+       rtx             parm_rtx;
2027
+       int             i;
2028
+       static const char zip_call_used_register[] = CALL_USED_REGISTERS;
2029
+
2030
+       INIT_CUMULATIVE_ARGS(cum_v, NULL, NULL, 0,0);
2031
+       cum = pack_cumulative_args(&cum_v);
2032
+       for (i=0; i<call_expr_nargs(exp); i++) {
2033
+
2034
+               parameter = CALL_EXPR_ARG(exp, i);
2035
+
2036
+               if ((!parameter) || (TREE_CODE(parameter)==ERROR_MARK))
2037
+                       return true;
2038
+               ttype = TREE_TYPE(parameter);
2039
+               gcc_assert(ttype);
2040
+               mode = ttype->type_common.mode;
2041
+
2042
+               if (pass_by_reference(&cum_v, mode, ttype, true)) {
2043
+                       mode = Pmode;
2044
+                       ttype = build_pointer_type(ttype);
2045
+               }
2046
+
2047
+               parm_rtx = zip_function_arg(cum, mode, ttype, 0);
2048
+               zip_function_arg_advance(cum, mode, ttype, 0);
2049
+               if (!parm_rtx)
2050
+                       continue;
2051
+
2052
+               // If it is a register
2053
+               //      and it is *NOT* a CALL_USED_REGISTER
2054
+               //      then we can't do this.
2055
+               //
2056
+               // Example: func(R1,..R4,R5)
2057
+               //      can be followed by func2(R1,.., up to R5)
2058
+               //      (not supported, though... just to simplify our test
2059
+               //      below)
2060
+               // Example: func(R1,..R4)
2061
+               //      cannot be followed by func2(R1,..,R5)
2062
+               //      We would blow R5 away by our prologue, even if it was
2063
+               //      properly set.
2064
+               // Example: func(R1,..R5)
2065
+               //      can be followed by func2(R1,.., up to R4)
2066
+               //      func2 may save R5 (which doesn't need saving) but that's
2067
+               //              irrelevant
2068
+               // Example: func(R1,..up to R4)
2069
+               //      can be followed by func2(R1,.., up to R4)
2070
+               //
2071
+               if (REG_P(parm_rtx)&&(REGNO(parm_rtx))
2072
+                               &&(REGNO(parm_rtx)<sizeof(zip_call_used_register))
2073
+                               &&(!zip_call_used_register[REGNO(parm_rtx)]))
2074
+                       return false;
2075
+       }
2076
+
2077
+       return true;
2078
+
2079
+       // We also need to check if the return types are the same ... or
2080
+       // will GCC handle that for us?
2081
+}
2082
+
2083
+void   zip_canonicalize_comparison(int *code, rtx *op0, rtx *op1,
2084
+               bool preserve_op0)
2085
+{
2086
+       ZIPDEBUGFLAG(dbg, false);
2087
+       bool    reverse = false;
2088
+
2089
+       if (dbg) fprintf(stderr, "CANONICALIZE ...%s\n", (preserve_op0)?"(Preserve Op0)":"");
2090
+       if (dbg) zip_debug_rtx_pfx("CODE", gen_rtx_fmt_ee((rtx_code)*code, VOIDmode, gen_rtx_REG(CCmode,zip_CC), const0_rtx));
2091
+       if (dbg) zip_debug_rtx_pfx("OP0 ", *op0);
2092
+       if (dbg) zip_debug_rtx_pfx("OP1 ", *op1);
2093
+
2094
+       // Z    ->      Z
2095
+       // NZ   ->      !Z
2096
+       // LT   ->      N
2097
+       // GE   ->      !N
2098
+       // LTU  ->      C
2099
+       // GEU  ->      !C
2100
+       //
2101
+       // LTE  ->      GTE w/ swapped operands
2102
+       // GT   ->      LT  w/ swapped operands
2103 122 dgisselq
+       // GTU  ->      LTU w/ swapped operands
2104
+       // LEU  ->      GEU w/ swapped operands
2105
+       //
2106 202 dgisselq
+
2107
+       if ((CONST_INT_P(*op0))||(GET_CODE(*op0) == PLUS)) {
2108 102 dgisselq
+               rtx     tmp = *op0;
2109 122 dgisselq
+               *op0 = *op1;
2110
+               *op1 = tmp;
2111
+               *code = (int)swap_condition((enum rtx_code)*code);
2112
+       }
2113
+
2114 202 dgisselq
+       if (*code == GTU) {
2115
+               if (REG_P(*op1)) {
2116
+                       //; Reverse the comparison
2117
+                       reverse = true;
2118
+               } else if (CONST_INT_P(*op1)) {
2119
+                       //; A >  B
2120
+                       //; A >= B+1
2121
+                       //; Add one to the integer constant,
2122
+                       //; And use a GEU comparison
2123
+                       *code = GEU;
2124
+                       *op1 = GEN_INT(INTVAL(*op1)+1);
2125
+               } else {
2126
+                       //; Reverse the comparison
2127
+                       reverse = true;
2128
+               }
2129 122 dgisselq
+       } else if (*code == LEU) {
2130 202 dgisselq
+               if (REG_P(*op1)) {
2131 122 dgisselq
+                       reverse = true;
2132
+               } else if (CONST_INT_P(*op1)) {
2133
+                       //; A <= B
2134 202 dgisselq
+                       //; A <  B+1
2135
+                       //; Add one to the integer constant,
2136
+                       //; And use a GTU comparison
2137
+                       *op1 = GEN_INT(INTVAL(*op1)+1);
2138
+                       *code = LTU;
2139
+               } else {
2140
+                       reverse = true;
2141
+               }
2142
+       } else if (*code == LE) {
2143
+               if (REG_P(*op1)) {
2144
+                       reverse = true;
2145
+               } else if (CONST_INT_P(*op1)) {
2146
+                       //; A <  B
2147
+                       //; A <= B-1
2148 122 dgisselq
+                       //; Add one to the integer constant,
2149 202 dgisselq
+                       //; And use a GTU comparison
2150
+                       *op1 = GEN_INT(INTVAL(*op1)-1);
2151
+                       *code = LT;
2152
+               } else {
2153
+                       reverse = true;
2154
+               }
2155
+       } else if (*code == GT) {
2156
+               if (REG_P(*op1)) {
2157
+                       //; Reverse the comparison
2158
+                       reverse = true;
2159
+               } else if (CONST_INT_P(*op1)) {
2160
+                       //; A >  B
2161
+                       //; A >= B+1
2162
+                       //; Add one to the integer constant,
2163
+                       //; And use a GTU comparison
2164
+                       *op1 = GEN_INT(INTVAL(*op1)+1);
2165
+                       *code = GE;
2166
+               } else {
2167
+                       reverse = true;
2168
+               }
2169
+       }
2170
+
2171
+       if (reverse) {
2172
+               rtx tem = *op0;
2173
+               *op0 = *op1;
2174
+               *op1 = tem;
2175
+               *code = (int)swap_condition((enum rtx_code)*code);
2176
+       }
2177
+}
2178
+
2179
+static bool
2180
+zip_fixed_condition_code_regs(unsigned int *a, unsigned int *b) {
2181
+       *a = zip_CC;
2182
+       *b = INVALID_REGNUM;
2183
+       return true;
2184
+}
2185
+
2186
+
2187
+/* totally buggy - we can't return pointers to nested functions */
2188
+static void
2189 122 dgisselq
+zip_asm_trampoline_template(FILE *f)
2190 202 dgisselq
+{
2191
+       fprintf(f, "\tbrev\t0,r1\n");
2192
+       fprintf(f, "\tldilo\t0,r1\n");
2193
+       fprintf(f, "\tjmp r1\n");
2194
+}
2195
+
2196
+/* Worker function for TARGET_TRAMPOLINE_INIT. */
2197 122 dgisselq
+static void
2198
+zip_trampoline_init(rtx m_tramp ATTRIBUTE_UNUSED,
2199
+       tree fndecl ATTRIBUTE_UNUSED,
2200
+       rtx chain_value ATTRIBUTE_UNUSED) {
2201
+// #warning "This needs to be filled out"
2202
+       abort();
2203
+}
2204
+
2205
+static tree
2206
+def_builtin(const char *name, enum insn_code icode, enum ZIP_BUILTIN_ID_CODE code,
2207 102 dgisselq
+       tree type)
2208
+{
2209 202 dgisselq
+       tree t = add_builtin_function(name,type,code, BUILT_IN_MD, NULL, NULL_TREE);
2210
+
2211 138 dgisselq
+       if(t) {
2212
+               zip_builtins[code] = t;
2213 102 dgisselq
+               zip_builtins_icode[code] = icode;
2214
+       }
2215
+
2216
+       return t;
2217
+
2218
+}
2219
+
2220
+void   zip_init_builtins(void) {
2221
+
2222
+  tree void_ftype_void = build_function_type_list(void_type_node, NULL_TREE);
2223
+#ifdef HAVE_zip_rtu
2224
+  def_builtin("zip_rtu", CODE_FOR_zip_rtu, ZIP_BUILTIN_RTU, void_ftype_void);
2225
+#endif
2226
+#ifdef HAVE_zip_halt
2227
+  def_builtin("zip_halt",  CODE_FOR_zip_halt,  ZIP_BUILTIN_HALT, void_ftype_void);
2228
+#endif
2229 202 dgisselq
+#ifdef HAVE_zip_busy
2230 102 dgisselq
+  def_builtin("zip_busy",  CODE_FOR_zip_busy,  ZIP_BUILTIN_BUSY, void_ftype_void);
2231
+#endif
2232
+#ifdef HAVE_zip_idle
2233
+  def_builtin("zip_idle", CODE_FOR_zip_idle, ZIP_BUILTIN_IDLE, void_ftype_void);
2234
+#endif
2235
+
2236
+#ifdef HAVE_zip_syscall
2237
+// Support int SYSCALL(callID, int a, int b, int c);
2238
+  def_builtin("zip_syscall", CODE_FOR_zip_syscall, ZIP_BUILTIN_SYSCALL,
2239
+                       build_function_type_list(void_type_node, NULL_TREE));
2240
+#endif
2241
+
2242
+#ifdef HAVE_zip_save_context
2243
+  def_builtin("zip_save_context", CODE_FOR_zip_save_context, ZIP_BUILTIN_SAVE_CONTEXT,
2244
+               build_function_type_list(void_type_node, ptr_type_node, 0));
2245
+#endif
2246
+
2247
+#ifdef HAVE_zip_restore_context
2248
+  def_builtin("zip_restore_context", CODE_FOR_zip_restore_context, ZIP_BUILTIN_RESTORE_CONTEXT,
2249 171 dgisselq
+       build_function_type_list(void_type_node, ptr_type_node, 0));
2250
+#endif
2251
+
2252 102 dgisselq
+#ifdef HAVE_zip_bitrev
2253
+  def_builtin("zip_bitrev", CODE_FOR_zip_bitrev, ZIP_BUILTIN_BITREV,
2254
+       build_function_type_list(unsigned_type_node, unsigned_type_node,
2255
+               NULL_TREE));
2256
+#endif
2257
+
2258
+#ifdef HAVE_zip_cc
2259
+  def_builtin("zip_cc", CODE_FOR_zip_cc, ZIP_BUILTIN_CC,
2260
+       build_function_type_list(unsigned_type_node, NULL_TREE));
2261
+#endif
2262
+
2263
+#ifdef HAVE_zip_ucc
2264
+  def_builtin("zip_ucc", CODE_FOR_zip_ucc, ZIP_BUILTIN_UCC,
2265
+       build_function_type_list(unsigned_type_node, NULL_TREE));
2266
+#endif
2267
+
2268
+}
2269
+
2270
+static tree
2271
+zip_builtin_decl(unsigned zip_builtin_code, bool initialize_p ATTRIBUTE_UNUSED)
2272
+{
2273
+  if (zip_builtin_code >= ZIP_BUILTIN_MAX)
2274
+    return error_mark_node;
2275
+
2276
+  return zip_builtins[zip_builtin_code];
2277
+}
2278
+
2279
+static rtx
2280
+zip_expand_builtin(tree exp, rtx target,
2281
+               rtx subtarget ATTRIBUTE_UNUSED,
2282
+               machine_mode tmode ATTRIBUTE_UNUSED,
2283 117 dgisselq
+               int     ignore ATTRIBUTE_UNUSED)
2284
+{
2285
+       tree    fndecl = TREE_OPERAND(CALL_EXPR_FN(exp), 0);
2286
+       bool    nonvoid = (TREE_TYPE(TREE_TYPE(fndecl)) != void_type_node);
2287
+       enum    ZIP_BUILTIN_ID_CODE code=(enum ZIP_BUILTIN_ID_CODE)DECL_FUNCTION_CODE(fndecl);
2288 102 dgisselq
+       enum    insn_code icode = zip_builtins_icode[code];
2289
+       rtx     pat, op[5];
2290
+       call_expr_arg_iterator  iter;
2291
+       tree    arg;
2292
+
2293
+       if ((code == ZIP_BUILTIN_SAVE_CONTEXT)
2294
+                       ||(code == ZIP_BUILTIN_RESTORE_CONTEXT)) {
2295
+               arg = first_call_expr_arg(exp, &iter);
2296
+               if (arg == error_mark_node)
2297
+                       return NULL_RTX;
2298
+               op[0] = expand_normal(arg);
2299
+               if (GET_CODE(op[0]) != REG)
2300
+                       op[0] = force_reg(Pmode, op[0]);
2301
+               pat = GEN_FCN(icode)(op[0]);
2302
+       } else if (code == ZIP_BUILTIN_BITREV) {
2303 202 dgisselq
+               arg = first_call_expr_arg(exp, &iter);
2304
+               if (arg == error_mark_node) {
2305 102 dgisselq
+                       return NULL_RTX;
2306
+               }
2307
+               op[0] = expand_normal(arg);
2308
+               if (!target)
2309
+                       target = gen_reg_rtx(SImode);
2310
+               pat = GEN_FCN(icode)(target, op[0]);
2311
+       } else if ((code == ZIP_BUILTIN_CC)||(code == ZIP_BUILTIN_UCC)) {
2312
+               if (!target)
2313
+                       target = gen_reg_rtx(SImode);
2314
+               pat = GEN_FCN(icode)(target);
2315
+       } else // RTU, HALT, IDLE
2316
+               pat = GEN_FCN(icode)();
2317
+       if (!pat)
2318
+               return NULL_RTX;
2319
+       emit_insn(pat);
2320
+       return (nonvoid ? target : const0_rtx);
2321
+}
2322
+
2323
+static bool
2324
+zip_scalar_mode_supported_p(enum machine_mode mode)
2325
+{
2326
+       if ((ZIP_HAS_DI)&&(mode == DImode))
2327
+               return true;
2328
+       if ((mode==SImode)||(mode==HImode)||(mode==QImode))
2329
+               return true;
2330
+       if (mode==SFmode)       // &&(ZIP_FPU)
2331 117 dgisselq
+               return true;    // If (!ZIP_CPU), will need to be emulated
2332 102 dgisselq
+       if (mode==DFmode)       // Must always be emulated
2333
+               return true;
2334
+       return false;
2335
+}
2336
+
2337
+static bool
2338
+zip_libgcc_floating_mode_supported_p(enum machine_mode mode)
2339
+{
2340
+       return ((mode)==SFmode)||((mode)==DFmode);
2341
+}
2342
+
2343
+static int
2344 202 dgisselq
+zip_address_cost(rtx addr ATTRIBUTE_UNUSED,
2345
+       enum machine_mode mode ATTRIBUTE_UNUSED,
2346
+       addr_space_t as ATTRIBUTE_UNUSED, bool spd ATTRIBUTE_UNUSED) {
2347
+       return 1;
2348
+}
2349
+
2350
+static bool
2351
+zip_mode_dependent_address_p(const_rtx addr ATTRIBUTE_UNUSED,
2352
+       addr_space_t as ATTRIBUTE_UNUSED) {
2353
+       return false;
2354
+}
2355 102 dgisselq
+
2356
+static void
2357
+zip_debug_print(const char *pfx, int lvl, const char *str) {
2358 202 dgisselq
+       int     i;
2359
+       i = lvl;
2360 102 dgisselq
+       if ((true)||(lvl == 0))
2361
+               fprintf(stderr, "%s", pfx);
2362
+       else
2363
+               i += strlen(pfx);
2364
+       while(i-->0)
2365
+               fprintf(stderr, "  ");
2366
+       fprintf(stderr, "%s\n", str);
2367
+}
2368
+
2369
+static void
2370
+zip_debug_print_m(const char *pfx, int lvl, const char *str, enum machine_mode m) {
2371
+       int     i;
2372
+
2373
+       i = lvl;
2374
+       if ((true)||(lvl == 0))
2375
+               fprintf(stderr, "%s", pfx);
2376
+       else
2377
+               i = lvl+strlen(pfx);
2378
+       while(i-->0)
2379
+               fprintf(stderr, "  ");
2380
+       switch(m) {
2381
+               case VOIDmode:
2382
+                       fprintf(stderr, "%s:V\n", str);
2383
+                       break;
2384
+               case BLKmode:
2385
+                       fprintf(stderr, "%s:BLK\n", str);
2386
+                       break;
2387
+               case BImode:
2388
+                       fprintf(stderr, "%s:BI\n", str);
2389
+                       break;
2390
+               case QImode:
2391
+                       fprintf(stderr, "%s:QI\n", str);
2392
+                       break;
2393
+               case HImode:
2394
+                       fprintf(stderr, "%s:HI\n", str);
2395
+                       break;
2396
+#ifdef HAVE_SImode
2397
+               case SImode:
2398
+                       fprintf(stderr, "%s:SI\n", str);
2399
+                       break;
2400
+#endif
2401
+#ifdef HAVE_DImode
2402
+               case DImode:
2403
+                       fprintf(stderr, "%s:DI\n", str);
2404
+                       break;
2405
+#endif
2406
+               case CCmode:
2407
+                       fprintf(stderr, "%s:CC\n", str);
2408
+                       break;
2409
+               default:
2410
+                       fprintf(stderr, "%s:?\n", str);
2411
+       }
2412
+}
2413
+
2414
+static void
2415
+zip_debug_rtx_1(const char *pfx, const_rtx x, int lvl) {
2416 202 dgisselq
+       if (x == NULL_RTX) {
2417 102 dgisselq
+               zip_debug_print(pfx, lvl, "(NULL-RTX)");
2418
+               return;
2419
+       } else if (GET_CODE(x) > NUM_RTX_CODE) {
2420 202 dgisselq
+               char    buf[64];
2421
+               sprintf(buf, "(BAD-RTX-CODE %d)", GET_CODE(x));
2422
+               zip_debug_print(pfx, lvl, buf);
2423
+               gcc_assert(0 && "Bad RTX Code");
2424
+               return;
2425
+       } switch(GET_CODE(x)) { // rtl.def
2426 122 dgisselq
+       case PARALLEL:
2427
+               zip_debug_print(pfx, lvl, "(PARALLEL");
2428
+               if (XVEC(x,0) != NULL)
2429 102 dgisselq
+                       for(int j=0; j<XVECLEN(x,0);j++)
2430
+                               zip_debug_rtx_1(pfx, XVECEXP(x,0,j), lvl+1);
2431
+               zip_debug_print(pfx, lvl, ")");
2432
+               debug_rtx(x);
2433
+               break;
2434
+       case INT_LIST: zip_debug_print(pfx, lvl, "(INT-LIST"); break;
2435
+       case SEQUENCE:
2436
+               zip_debug_print(pfx, lvl, "(SEQUENCE");
2437
+               for(int j=0; j<XVECLEN(x,0);j++)
2438
+                       zip_debug_rtx_1(pfx, XVECEXP(x,0,j), lvl+1);
2439
+               zip_debug_print(pfx, lvl, ")");
2440
+               debug_rtx(x);
2441
+               break;
2442
+       case ADDRESS: zip_debug_print(pfx, lvl, "(ADDRESS"); break;
2443 117 dgisselq
+       case DEBUG_INSN: zip_debug_print(pfx, lvl, "(DEBUG-INSN"); break;
2444 102 dgisselq
+       case INSN:
2445
+               zip_debug_print(pfx, lvl, "(INSN");
2446 122 dgisselq
+               /*
2447
+               { const rtx_insn *tmp_rtx;
2448 202 dgisselq
+               for(tmp_rtx = as_a <const rtx_insn *>(x); tmp_rtx != 0; tmp_rtx = NEXT_INSN(tmp_rtx)) {
2449
+                       zip_debug_rtx_1(tmp_rtx, lvl+1);
2450
+               }}
2451 122 dgisselq
+               */
2452
+               zip_debug_rtx_1(pfx, PATTERN(x), lvl+1);
2453
+               zip_debug_print(pfx, lvl, ")");
2454 102 dgisselq
+               debug_rtx(x);
2455 122 dgisselq
+               break;
2456
+       case JUMP_INSN: zip_debug_print(pfx, lvl, "(JUMP-INSN");
2457
+               zip_debug_rtx_1(pfx, PATTERN(x), lvl+1);
2458
+               zip_debug_print(pfx, lvl, ")");
2459
+               /*
2460
+               if (JUMP_LABEL(x)) {
2461
+                       if (GET_CODE(JUMP_LABEL(x)) == LABEL_REF) {
2462 102 dgisselq
+                               char    buf[64];
2463
+                               sprintf(buf, "(LABEL *.L%d))", CODE_LABEL_NUMBER(LABEL_REF_LABEL(JUMP_LABEL(x))));
2464
+                               zip_debug_print(pfx, lvl+1, buf);
2465
+                       } else if (GET_CODE(JUMP_LABEL(x))==CODE_LABEL) {
2466
+                               char    buf[64];
2467
+                               sprintf(buf, "(CODE_LABEL *.L%d))", CODE_LABEL_NUMBER(JUMP_LABEL(x)));
2468
+                               zip_debug_print(pfx, lvl+1, buf);
2469
+                       } else
2470
+                       zip_debug_print(pfx, lvl+1, "(w/Label))");
2471
+               } else
2472
+                       zip_debug_print(pfx, lvl+1, "(NO label))");
2473
+               debug_rtx(x);
2474 117 dgisselq
+               */
2475 102 dgisselq
+               break;
2476
+       case CALL:
2477 111 dgisselq
+               zip_debug_print(pfx, lvl, "(CALL (Adr) (Args)");
2478
+               zip_debug_rtx_1(pfx, XEXP(x,0), lvl+1);
2479
+               zip_debug_rtx_1(pfx, XEXP(x,1), lvl+1);
2480 102 dgisselq
+               zip_debug_print(pfx, lvl, ")");
2481 111 dgisselq
+               break;
2482
+       case CALL_INSN: zip_debug_print(pfx, lvl, "(CALL-INSN");
2483
+               debug_rtx(x);
2484
+               break;
2485
+       case BARRIER: zip_debug_print(pfx, lvl, "(BARRIER)"); break;
2486
+       case RETURN: zip_debug_print(pfx, lvl, "(RETURN)"); break;
2487
+       case NOTE:
2488
+               {       char buf[128];
2489
+                       sprintf(buf, "(NOTE %s)", GET_REG_NOTE_NAME(GET_MODE(x)));
2490
+                       zip_debug_print(pfx, lvl, buf);
2491 102 dgisselq
+               }break;
2492 111 dgisselq
+       case COND_EXEC: zip_debug_print(pfx, lvl, "(COND_EXEC)");
2493
+               debug_rtx(x);
2494
+               break;
2495 102 dgisselq
+       case ASM_INPUT: zip_debug_print(pfx, lvl, "(ASM INPUT)"); break;
2496
+       case ASM_OPERANDS: zip_debug_print(pfx, lvl, "(ASM OPERANDS)"); break;
2497
+       case UNSPEC: zip_debug_print(pfx, lvl, "(UNSPEC)"); break;
2498
+       case UNSPEC_VOLATILE: zip_debug_print(pfx, lvl, "(UNSPEC_VOLATILE)"); break;
2499
+       case CODE_LABEL:
2500
+               {
2501
+                       char    buf[128];
2502
+                       sprintf(buf, "(CODE_LABEL *.L%d)", CODE_LABEL_NUMBER(x));
2503
+                       zip_debug_print_m(pfx, lvl, buf, GET_MODE(x));
2504
+               } break;
2505
+       case SET:
2506
+               zip_debug_print_m(pfx, lvl, "(SET", GET_MODE(x));
2507
+               zip_debug_rtx_1(pfx, SET_DEST(x),lvl+1);
2508
+               zip_debug_rtx_1(pfx, SET_SRC(x),lvl+1);
2509
+               zip_debug_print(pfx, lvl, ")");
2510
+               debug_rtx(x);
2511
+               break;
2512
+       case REG: {
2513
+               char buf[25], mstr[4];
2514
+               mstr[0] = '\0';
2515
+               if (GET_MODE(x) == QImode)
2516
+                       strcpy(mstr, ":QI");
2517
+               else if (GET_MODE(x) == HImode)
2518
+                       strcpy(mstr, ":HI");
2519
+               else if (GET_MODE(x) == VOIDmode)
2520
+                       strcpy(mstr, ":V");
2521 192 dgisselq
+               if (REGNO(x) == zip_PC)
2522 111 dgisselq
+                       sprintf(buf, "(PC%s)", mstr);
2523 102 dgisselq
+               else if (REGNO(x) == zip_CC)
2524
+                       sprintf(buf, "(CC%s)", mstr);
2525
+               else if (REGNO(x) == zip_SP)
2526
+                       sprintf(buf, "(SP%s)", mstr);
2527 117 dgisselq
+               else if (REGNO(x) == zip_FP)
2528
+                       sprintf(buf, "(REG%s FP)", mstr);
2529 102 dgisselq
+               else if (REGNO(x) == zip_GOT)
2530 117 dgisselq
+                       sprintf(buf, "(REG%s GBL)", mstr);
2531 102 dgisselq
+               else if (FUNCTION_VALUE_REGNO_P(REGNO(x)))
2532 122 dgisselq
+                       sprintf(buf, "(REG%s RTN-VL)", mstr);
2533 127 dgisselq
+               else if (REGNO(x) == RETURN_ADDRESS_REGNUM)
2534
+                       sprintf(buf, "(REG%s RTN-AD)", mstr);
2535 202 dgisselq
+               else
2536
+                       sprintf(buf, "(REG%s %d)", mstr, REGNO(x));
2537
+               if (mstr[0])
2538
+                       zip_debug_print(pfx, lvl, buf);
2539 127 dgisselq
+               else
2540
+                       zip_debug_print_m(pfx, lvl, buf, GET_MODE(x));
2541 102 dgisselq
+               } break;
2542 127 dgisselq
+       case IF_THEN_ELSE: // 51
2543 102 dgisselq
+               zip_debug_print(pfx, lvl, "(IF-THEN-ELSE");
2544 127 dgisselq
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2545 102 dgisselq
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2546 127 dgisselq
+               zip_debug_rtx_1(pfx, XEXP(x,2),lvl+1);
2547 102 dgisselq
+               zip_debug_print(pfx, lvl, ")");
2548 127 dgisselq
+               break;
2549 102 dgisselq
+       case PC:
2550 127 dgisselq
+               zip_debug_print(pfx, lvl, "(PC)");
2551 102 dgisselq
+               break;
2552 127 dgisselq
+       case CC0:
2553 102 dgisselq
+               zip_debug_print(pfx, lvl, "(CC0)");
2554 127 dgisselq
+               break;
2555 122 dgisselq
+       case COMPARE:
2556 127 dgisselq
+               zip_debug_print_m(pfx, lvl, "(COMPARE", GET_MODE(x));
2557
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2558
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2559
+               zip_debug_print(pfx, lvl, ")");
2560
+               break;
2561 102 dgisselq
+       case CONST:
2562
+               zip_debug_print_m(pfx, lvl, "(CONST", GET_MODE(x));
2563
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2564
+               zip_debug_print(pfx, lvl, ")");
2565
+               break;
2566
+       case CONST_INT:
2567
+               { char buf[128];
2568
+               if (GET_MODE(x)==QImode)
2569
+                       sprintf(buf, "(CONST_INT:QI %ld)", (long)INTVAL(x));
2570
+               else if (GET_MODE(x)==VOIDmode)
2571
+                       sprintf(buf, "(CONST_INT:V %ld, %016lx)", (long)INTVAL(x),
2572
+                               (unsigned long)INTVAL(x));
2573
+               else
2574
+                       sprintf(buf, "(CONST_INT:? %ld)", (long)INTVAL(x));
2575
+               zip_debug_print(pfx, lvl, buf);
2576 127 dgisselq
+               } break;
2577 102 dgisselq
+       case LABEL_REF:
2578
+               { char buf[256];
2579
+               sprintf(buf, "(LABEL *.L%d)", CODE_LABEL_NUMBER(LABEL_REF_LABEL(x)));
2580
+               zip_debug_print(pfx, lvl, buf);
2581 111 dgisselq
+               }
2582
+               break;
2583
+       case SYMBOL_REF:
2584
+               {
2585
+                       char buf[1024];
2586 102 dgisselq
+                       sprintf(buf, "(SYMBOL: %s)", XSTR(x,0));
2587 192 dgisselq
+                       // fprintf(file, "%s", XSTR(x,0));
2588 202 dgisselq
+                       zip_debug_print(pfx, lvl, buf);
2589
+               }
2590 102 dgisselq
+               break;
2591 202 dgisselq
+       case MEM:
2592
+               zip_debug_print_m(pfx, lvl, "(MEM", GET_MODE(x));
2593 102 dgisselq
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2594 135 dgisselq
+               zip_debug_print(pfx, lvl, ")");
2595 102 dgisselq
+               break;
2596
+       /*
2597
+       case VALUE:
2598 122 dgisselq
+               {
2599 111 dgisselq
+                       char buf[64];
2600
+                       sprintf(buf, "(VALUE: %d)", INTVAL(XEXP,0));
2601
+                       zip_debug_print_m(pfx, lvl, "buf", GET_MODE(x));
2602 102 dgisselq
+               }
2603
+               break;
2604
+       */
2605 202 dgisselq
+       case PLUS:
2606 102 dgisselq
+               zip_debug_print_m(pfx, lvl, "(PLUS", GET_MODE(x));
2607
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2608
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2609
+               zip_debug_print(pfx, lvl, ")");
2610
+               break;
2611
+       case MINUS:
2612
+               zip_debug_print_m(pfx, lvl, "(MINUS", GET_MODE(x));
2613
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2614
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2615
+               zip_debug_print(pfx, lvl, ")");
2616
+               break;
2617
+       case AND:
2618
+               zip_debug_print_m(pfx, lvl, "(AND", GET_MODE(x));
2619
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2620
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2621
+               zip_debug_print(pfx, lvl, ")");
2622
+               break;
2623
+       case IOR:
2624
+               zip_debug_print_m(pfx, lvl, "(OR", GET_MODE(x));
2625
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2626
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2627
+               zip_debug_print(pfx, lvl, ")");
2628
+               break;
2629
+       case XOR:
2630
+               zip_debug_print_m(pfx, lvl, "(XOR", GET_MODE(x));
2631
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2632
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2633
+               zip_debug_print(pfx, lvl, ")");
2634
+               break;
2635
+       case MULT:
2636
+               zip_debug_print_m(pfx, lvl, "(MULT", GET_MODE(x));
2637
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2638
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2639
+               zip_debug_print(pfx, lvl, ")");
2640
+               break;
2641
+       case EQ:        //
2642
+               zip_debug_print_m(pfx, lvl, "(EQ", GET_MODE(x));
2643
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2644
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2645
+               zip_debug_print(pfx, lvl, ")");
2646
+               break;
2647
+       case NE:        //
2648
+               zip_debug_print_m(pfx, lvl, "(NE", GET_MODE(x));
2649
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2650
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2651
+               zip_debug_print(pfx, lvl, ")");
2652
+               break;
2653
+       case GE:        //
2654
+               zip_debug_print_m(pfx, lvl, "(GE", GET_MODE(x));
2655
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2656
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2657
+               zip_debug_print(pfx, lvl, ")");
2658
+               break;
2659
+       case GT:        //
2660
+               zip_debug_print_m(pfx, lvl, "(GT", GET_MODE(x));
2661
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2662
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2663
+               zip_debug_print(pfx, lvl, ")");
2664
+               break;
2665
+       case LE:        //
2666
+               zip_debug_print_m(pfx, lvl, "(LE", GET_MODE(x));
2667
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2668
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2669
+               zip_debug_print(pfx, lvl, ")");
2670
+               break;
2671
+       case LT:        //
2672
+               zip_debug_print_m(pfx, lvl, "(LT", GET_MODE(x));
2673
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2674
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2675
+               zip_debug_print(pfx, lvl, ")");
2676
+               break;
2677
+       case GEU:       //
2678
+               zip_debug_print_m(pfx, lvl, "(GEU", GET_MODE(x));
2679
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2680
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2681
+               zip_debug_print(pfx, lvl, ")");
2682
+               break;
2683
+       case GTU:       //
2684
+               zip_debug_print_m(pfx, lvl, "(GTU", GET_MODE(x));
2685
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2686
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2687
+               zip_debug_print(pfx, lvl, ")");
2688
+               break;
2689
+       case LEU:       //
2690
+               zip_debug_print_m(pfx, lvl, "(LEU", GET_MODE(x));
2691
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2692
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2693
+               zip_debug_print(pfx, lvl, ")");
2694
+               break;
2695
+       case LTU:       //
2696
+               zip_debug_print_m(pfx, lvl, "(LTU", GET_MODE(x));
2697
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2698
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2699
+               zip_debug_print(pfx, lvl, ")");
2700
+               break;
2701
+       case SCRATCH:   //
2702
+               zip_debug_print_m(pfx, lvl, "(SCRATCH)", GET_MODE(x));
2703
+               break;
2704
+       case SUBREG:
2705
+               { char buf[64], mstr[8];
2706
+               if (GET_MODE(x) == QImode)
2707
+                       strcpy(mstr, ":QI");
2708
+               else if (GET_MODE(x) == HImode)
2709
+                       strcpy(mstr, ":HI");
2710
+               else if (GET_MODE(x) == SImode)
2711
+                       strcpy(mstr, ":SI");
2712
+               else if (GET_MODE(x) == DImode)
2713
+                       strcpy(mstr, ":DI");
2714
+               else if (GET_MODE(x) == SFmode)
2715
+                       strcpy(mstr, ":SF");
2716
+               else if (GET_MODE(x) == DFmode)
2717
+                       strcpy(mstr, ":DF");
2718
+               else if (GET_MODE(x) == VOIDmode)
2719
+                       strcpy(mstr, ":V");
2720
+               else
2721
+                       strcpy(mstr, ":?");
2722
+               if (REG_P(XEXP(x,0))) {
2723
+                       int hreg = REGNO(XEXP(x,0)), mod = GET_MODE(XEXP(x,0)),
2724
+                               sb = SUBREG_BYTE(x);
2725 202 dgisselq
+                       if (mod==SFmode)
2726
+                       sprintf(buf,"(SUBREG%s (REG:SF %d)/%d)",mstr,hreg, sb);
2727
+                       else if (mod==DFmode)
2728
+                       sprintf(buf,"(SUBREG%s (REG:DF %d)/%d)",mstr,hreg, sb);
2729
+                       else if (mod==DImode)
2730
+                       sprintf(buf,"(SUBREG%s (REG:DI %d)/%d)",mstr,hreg, sb);
2731
+                       else if (mod==SImode)
2732 209 dgisselq
+                       sprintf(buf,"(SUBREG%s (REG:SI %d)/%d)",mstr,hreg, sb);
2733
+                       else if (mod==HImode)
2734
+                       sprintf(buf,"(SUBREG%s (REG:HI %d)/%d)",mstr,hreg, sb);
2735
+                       else if (mod==QImode)
2736
+                       sprintf(buf,"(SUBREG%s (REG:QI %d)/%d)",mstr,hreg, sb);
2737
+                       else if (mod==VOIDmode)
2738 202 dgisselq
+                       sprintf(buf,"(SUBREG%s (REG:V %d)/%d)",mstr,hreg, sb);
2739
+                       else
2740
+                       sprintf(buf,"(SUBREG%s %d:?/%d)",mstr,hreg, sb);
2741
+                       zip_debug_print(pfx, lvl, buf);
2742 111 dgisselq
+               } else if (MEM_P(XEXP(x,0))) {
2743 202 dgisselq
+                       sprintf(buf, "(SUBREG%s /%d", mstr,SUBREG_BYTE(x));
2744
+                       zip_debug_print(pfx, lvl, buf);
2745 209 dgisselq
+                       zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2746
+                       zip_debug_print(pfx, lvl, ")");
2747
+               } else {
2748
+                       sprintf(buf, "(SUBREG%s UNK /%d", mstr,SUBREG_BYTE(x));
2749
+                       zip_debug_print(pfx, lvl, buf);
2750
+                       zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2751
+                       zip_debug_print(pfx, lvl, ")");
2752
+               }}
2753 202 dgisselq
+               break;
2754
+       case ASHIFT:
2755
+               zip_debug_print_m(pfx, lvl, "(ASHIFT", GET_MODE(x));
2756
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2757
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2758
+               zip_debug_print(pfx, lvl, ")");
2759
+               break;
2760
+       case ASHIFTRT:
2761 111 dgisselq
+               zip_debug_print_m(pfx, lvl, "(ASHIFTRT", GET_MODE(x));
2762
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2763 202 dgisselq
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2764 111 dgisselq
+               zip_debug_print(pfx, lvl, ")");
2765
+               break;
2766
+       case LSHIFTRT:
2767
+               zip_debug_print_m(pfx, lvl, "(LSHIFTRT", GET_MODE(x));
2768 202 dgisselq
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2769 111 dgisselq
+               zip_debug_rtx_1(pfx, XEXP(x,1),lvl+1);
2770
+               zip_debug_print(pfx, lvl, ")");
2771
+               break;
2772
+       case ZERO_EXTRACT:
2773
+               zip_debug_print_m(pfx, lvl, "(ZERO_EXTRACT", GET_MODE(x));
2774 127 dgisselq
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2775
+               zip_debug_print(pfx, lvl, ")");
2776
+               break;
2777
+       case ZERO_EXTEND:
2778
+               zip_debug_print_m(pfx, lvl, "(ZERO_EXTEND", GET_MODE(x));
2779
+               zip_debug_rtx_1(pfx, XEXP(x,0),lvl+1);
2780
+               zip_debug_print(pfx, lvl, ")");
2781
+               break;
2782
+       default:
2783
+               { char buf[128];
2784
+               sprintf(buf, "(? = %d) -- calling DEBUG-RTX", GET_CODE(x));
2785
+               zip_debug_print(pfx, lvl, buf);
2786
+               debug_rtx(x);
2787
+               } break;
2788
+       }
2789
+}
2790
+
2791
+void
2792 202 dgisselq
+zip_debug_rtx_pfx(const char *pfx, const_rtx x) {
2793
+       zip_debug_rtx_1(pfx, x, 0);
2794
+}
2795
+
2796
+void
2797
+zip_debug_rtx(const_rtx x) {
2798
+       zip_debug_rtx_pfx("", x);
2799
+}
2800
+
2801
+void
2802 102 dgisselq
+zip_debug_ccode(int ccode) {
2803 111 dgisselq
+       switch(ccode) {
2804 102 dgisselq
+       case    EQ: fprintf(stderr, "EQ"); break;
2805
+       case    NE: fprintf(stderr, "NE"); break;
2806
+       case    GE: fprintf(stderr, "GE"); break;
2807
+       case    LT: fprintf(stderr, "LT"); break;
2808
+       case    LTU: fprintf(stderr, "LTU"); break;
2809
+       case    GEU: fprintf(stderr, "GEU"); break;
2810
+       case    GT: fprintf(stderr, "GT[!]"); break;
2811
+       case    LE: fprintf(stderr, "LE[!]"); break;
2812
+       case    GTU: fprintf(stderr, "GTU[!]"); break;
2813
+       case    LEU: fprintf(stderr, "LEU[!]"); break;
2814
+       default:
2815
+               fprintf(stderr, "%d", ccode); break;
2816
+       }
2817
+}
2818
+
2819
+void
2820
+zip_debug_insn(rtx_insn *insn ATTRIBUTE_UNUSED) {
2821
+}
2822 142 dgisselq
+
2823
+void
2824
+zip_debug_bb(basic_block bb) {
2825
+       rtx_insn        *insn;
2826
+
2827
+       fprintf(stderr, "************ BASIC-BLOCK ***************\n");
2828 202 dgisselq
+       FOR_BB_INSNS(bb, insn)
2829 142 dgisselq
+       {
2830 202 dgisselq
+               zip_debug_rtx(insn);
2831
+       }
2832
+}
2833
+
2834 142 dgisselq
+
2835
+static bool
2836
+zip_legitimate_opb(rtx x, bool strict)
2837
+{
2838
+       ZIPDEBUGFLAG(dbg, false);
2839
+
2840 102 dgisselq
+       if (dbg) fprintf(stderr, "ZIP-LEGITIMATE-OPB\n");
2841
+       if (dbg) zip_debug_rtx_pfx("Test: ", x);
2842
+
2843
+       if (NULL_RTX == x)
2844
+               return false;
2845
+       else if ((GET_MODE(x) != QImode)
2846
+                       &&(GET_MODE(x) != HImode)
2847
+                       &&(GET_MODE(x) != SImode)
2848
+                       &&(GET_MODE(x) != VOIDmode)) {
2849
+               if (dbg) fprintf(stderr, "ZIP-LEGITIMATE-OPB -> Mode failure\n");
2850
+               return false;
2851
+       } else if ((strict)&&(REG_P(x))) {
2852
+               if (REGNO(x)<zip_CC) {
2853
+                       if (dbg) fprintf(stderr, "ZIP-LEGITIMATE-OPB -> (Reg)\n");
2854
+                       return true;
2855
+               } else return false;
2856 122 dgisselq
+       } else if (register_operand(x, GET_MODE(x))) {
2857 102 dgisselq
+               // This also handles subregs
2858 202 dgisselq
+               if (dbg) fprintf(stderr, "ZIP-LEGITIMATE-OPB -> (Reg)\n");
2859 102 dgisselq
+               return true;
2860 111 dgisselq
+       } else if ((CONST_INT_P(x))
2861 102 dgisselq
+               &&(INTVAL(x) >= zip_min_opb_imm)
2862
+               &&(INTVAL(x) <= zip_max_opb_imm)) {
2863
+               if (dbg) fprintf(stderr, "ZIP-LEGITIMATE-OPB -> YES! (Const) %ld <= %ld <= %ld\n", (long)zip_min_opb_imm, (long)INTVAL(x), (long)zip_max_opb_imm);
2864
+               return true;
2865 202 dgisselq
+       // } else if ((GET_CODE(x) == LABEL_REF)||(GET_CODE(x)==CODE_LABEL)) {
2866
+               // return true;
2867
+       } else if (GET_CODE(x) == PLUS) {
2868
+               // Is it a valid register?
2869 122 dgisselq
+               rtx     regrtx = XEXP(x, 0);
2870 102 dgisselq
+               if ((!strict)&&(!REG_P(regrtx))) {
2871 122 dgisselq
+                       if (dbg) fprintf(stderr, "ZIP-LEGITIMATE-OPB -> No (No reg in +%s)\n",
2872
+                       (GET_CODE(XEXP(x,1))==REG)?", reg in op[1]":"");
2873
+                       return false;
2874
+               } else if ((strict)&&((!REG_P(XEXP(x,0)))||(REGNO(XEXP(x,0))>=zip_CC))) {
2875
+                       return false;
2876
+               } if ((GET_CODE(XEXP(x, 1)) == CONST_INT)
2877
+                       &&(INTVAL(XEXP(x, 1)) <= zip_max_anchor_offset)
2878
+                       &&(INTVAL(XEXP(x, 1)) >= zip_min_anchor_offset)) {
2879
+                       if (dbg) fprintf(stderr, "ZIP-LEGITIMATE-OPB -> YES! (reg+int)\n");
2880 111 dgisselq
+                       // if((INTVAL(XEXP(x,1))<0)&&(REGNO(XEXP(x,0))==zip_SP))
2881
+                               // gcc_unreachable();
2882
+                       return true;
2883 136 dgisselq
+               } if ((GET_CODE(XEXP(x, 1)) == LABEL_REF)
2884 111 dgisselq
+                       ||(GET_CODE(XEXP(x, 1)) == CODE_LABEL)
2885 122 dgisselq
+                       ||(GET_CODE(XEXP(x, 1)) == SYMBOL_REF)) {
2886
+                       // While we can technically support this, the problem
2887 102 dgisselq
+                       // is that the symbol address could be anywhere, and we
2888
+                       // have no way of recovering if it's outside of our
2889 202 dgisselq
+                       // 14 allowable bits.
2890
+                       if (dbg) fprintf(stderr, "ZIP-LEGITIMATE-OPB -> No. (reg+lbl)\n");
2891 111 dgisselq
+                       return false;
2892 102 dgisselq
+               }
2893
+       }
2894 122 dgisselq
+
2895 102 dgisselq
+       if (dbg) fprintf(stderr, "ZIP-LEGITIMATE-OPB -> No\n");
2896
+       if (dbg) zip_debug_rtx(x);
2897
+       return false;
2898
+}
2899 111 dgisselq
+
2900 103 dgisselq
+static bool
2901
+zip_legitimate_move_operand_p(machine_mode mode ATTRIBUTE_UNUSED, rtx x, bool strict) {
2902 102 dgisselq
+       const bool      dbg = ((ZIP_ALL_DEBUG_ON)||(false))&&(!ZIP_ALL_DEBUG_OFF);
2903
+
2904 122 dgisselq
+       if (dbg) fprintf(stderr, "ZIP-VALID-MOVE-OPERAND\n");
2905 102 dgisselq
+       if (dbg) zip_debug_rtx_pfx("VMov?: ", x);
2906
+
2907
+       if (!zip_legitimate_opb(x, strict))
2908
+               return false;
2909
+       else if ((GET_CODE(x)==PLUS)&&(CONST_INT_P(XEXP(x,1)))) {
2910 111 dgisselq
+               if ((INTVAL(XEXP(x, 1)) > zip_max_mov_offset)
2911 102 dgisselq
+                       ||(INTVAL(XEXP(x, 1)) < zip_min_mov_offset)) {
2912
+                       if (dbg) fprintf(stderr, "ZIP-VALID-MOVE-OPERAND -> NO! (reg+int), int out of bounds: %ld\n", (long)INTVAL(XEXP(x,1)));
2913
+                       return false;
2914
+               }
2915 111 dgisselq
+       }
2916 102 dgisselq
+
2917
+       if (dbg) fprintf(stderr, "ZIP-VALID-MOVE-OPERAND -> Yes\n");
2918
+       if (dbg) zip_debug_rtx(x);
2919
+       return true;
2920
+}
2921
+
2922 202 dgisselq
+int
2923 102 dgisselq
+zip_pd_mov_operand(rtx op)
2924
+{
2925
+       const bool      dbg = ((ZIP_ALL_DEBUG_ON)||(false))&&(!ZIP_ALL_DEBUG_OFF);
2926
+
2927 122 dgisselq
+       if (dbg) fprintf(stderr, "ZIP-VALID-MOV(predicate) for OPERAND\n");
2928 102 dgisselq
+       return zip_legitimate_move_operand_p(VOIDmode, op, !can_create_pseudo_p());
2929 122 dgisselq
+}
2930
+
2931
+int
2932 135 dgisselq
+zip_pd_mvimm_operand(rtx op)
2933 102 dgisselq
+{
2934
+       const bool      dbg = ((ZIP_ALL_DEBUG_ON)||(false))&&(!ZIP_ALL_DEBUG_OFF);
2935
+
2936
+       if (dbg) fprintf(stderr, "ZIP-VALID-MVIMM(predicate) for OPERAND\n");
2937 122 dgisselq
+       if (!CONST_INT_P(op))
2938 102 dgisselq
+               return false;
2939 122 dgisselq
+       if (INTVAL(op) > zip_max_mov_offset)
2940 102 dgisselq
+               return false;
2941
+       if (INTVAL(op) < zip_min_mov_offset)
2942
+               return false;
2943
+       return true;
2944
+}
2945 202 dgisselq
+
2946 102 dgisselq
+int
2947
+zip_pd_imm_operand(rtx op)
2948
+{
2949
+       const bool      dbg = ((ZIP_ALL_DEBUG_ON)||(false))&&(!ZIP_ALL_DEBUG_OFF);
2950
+
2951
+       if (dbg) fprintf(stderr, "ZIP-VALID-IMM(predicate) for OPERAND\n");
2952 111 dgisselq
+       if (!CONST_INT_P(op))
2953
+               return false;
2954 202 dgisselq
+       if (INTVAL(op) > zip_max_anchor_offset)
2955 111 dgisselq
+               return false;
2956
+       if (INTVAL(op) < zip_min_anchor_offset)
2957
+               return false;
2958
+       return true;
2959
+}
2960
+
2961
+int
2962
+zip_address_operand(rtx op)
2963
+{
2964
+       const bool      dbg = ((ZIP_ALL_DEBUG_ON)||(false))&&(!ZIP_ALL_DEBUG_OFF);
2965
+
2966
+       if (dbg) fprintf(stderr, "ZIP-ADDRESS for OPERAND\n");
2967
+       if ((REG_P(op))&&(REGNO(op)==zip_CC))
2968
+               return false;
2969 202 dgisselq
+       else if ((GET_CODE(op) == PLUS)&&(REG_P(XEXP(op,0)))
2970 111 dgisselq
+                       &&(REGNO(XEXP(op,0))==zip_CC))
2971
+               return false;
2972
+       else
2973
+               return zip_legitimate_opb(op, !can_create_pseudo_p());
2974
+}
2975
+
2976
+int
2977
+zip_pd_opb_operand(rtx op)
2978
+{
2979
+       ZIPDEBUGFLAG(dbg, false);
2980
+
2981
+       if (dbg) fprintf(stderr, "ZIP-OPB(predicate) for OPERAND\n");
2982 102 dgisselq
+       return zip_legitimate_opb(op, false); //, !can_create_pseudo_p());
2983
+}
2984 202 dgisselq
+
2985 102 dgisselq
+int
2986
+zip_ct_address_operand(rtx op)
2987 111 dgisselq
+{
2988
+       ZIPDEBUGFLAG(dbg, false);
2989
+
2990
+       if (dbg) fprintf(stderr, "ZIP-ADDRESS(constraint) for OPERAND\n");
2991
+       return zip_legitimate_opb(op, !can_create_pseudo_p());
2992
+}
2993
+
2994 102 dgisselq
+int
2995
+zip_const_address_operand(rtx x) {
2996
+       ZIPDEBUGFLAG(dbg, false);
2997 111 dgisselq
+
2998 102 dgisselq
+       if (dbg) fprintf(stderr, "is ZIP-CONST-ADDRESS?\n");
2999 202 dgisselq
+       if (dbg) zip_debug_rtx(x);
3000 102 dgisselq
+       if ((GET_MODE(x) != SImode)&&(GET_MODE(x) != VOIDmode)) {
3001 111 dgisselq
+               fprintf(stderr, "is ZIP-CONST-ADDRESS? -> NO, BAD MODE\n");
3002 122 dgisselq
+               return false;
3003 102 dgisselq
+       }
3004
+       if ((GET_CODE(x) == LABEL_REF)
3005
+                       ||(GET_CODE(x) == CODE_LABEL)
3006
+                       ||(GET_CODE(x) == SYMBOL_REF)) {
3007
+               if (dbg) fprintf(stderr, "is ZIP-CONST-ADDRESS? -> YES! (LBL)\n");
3008 202 dgisselq
+               return true;
3009 102 dgisselq
+       } else if (CONST_INT_P(x)) {
3010
+               if (dbg) fprintf(stderr, "is ZIP-CONST-ADDRESS? -> YES! (INT)\n");
3011 111 dgisselq
+               return true;
3012 102 dgisselq
+       } else if (GET_CODE(x) == PLUS) {
3013
+               if (dbg) fprintf(stderr, "is ZIP-CONST-ADDRESS(PLUS)\n");
3014
+               return ((zip_const_address_operand(XEXP(x,0)))
3015
+                       &&(CONST_INT_P(XEXP(x,1))));
3016 202 dgisselq
+       } else if (GET_CODE(x) == MINUS) {
3017 102 dgisselq
+               if (dbg) fprintf(stderr, "is ZIP-CONST-ADDRESS(MINUS)\n");
3018
+               return ((zip_const_address_operand(XEXP(x,0)))
3019
+                       &&(zip_const_address_operand(XEXP(x,1))));
3020 127 dgisselq
+       }
3021
+
3022 102 dgisselq
+       if (dbg) fprintf(stderr, "is ZIP-CONST-ADDRESS? -> No\n");
3023 127 dgisselq
+       if (dbg) zip_debug_rtx(x);
3024 102 dgisselq
+       return false;
3025
+}
3026
+
3027 127 dgisselq
+int
3028 102 dgisselq
+zip_ct_const_address_operand(rtx x) {
3029
+       ZIPDEBUGFLAG(dbg, false);
3030 127 dgisselq
+
3031 102 dgisselq
+       if (dbg) fprintf(stderr, "ZIP-CONST-ADDRESS(constraint)\n");
3032
+       return zip_const_address_operand(x);
3033
+}
3034
+
3035
+int
3036
+zip_pd_const_address_operand(rtx x) {
3037
+       ZIPDEBUGFLAG(dbg, false);
3038
+
3039
+       if (dbg) fprintf(stderr, "ZIP-CONST-ADDRESS(predicate)\n");
3040
+       return zip_const_address_operand(x);
3041
+}
3042
+
3043
+
3044
+static bool
3045
+zip_legitimate_address_p(machine_mode mode ATTRIBUTE_UNUSED, rtx x, bool strict)
3046
+{
3047
+       ZIPDEBUGFLAG(dbg, false);
3048
+
3049 202 dgisselq
+       if (dbg) fprintf(stderr, "Zip-LEGITIMATE-ADDRESS-P\n");
3050 102 dgisselq
+       if (dbg) zip_debug_rtx(x);
3051
+
3052
+       // Only insist the register be a valid register if strict is true
3053
+       if (zip_legitimate_opb(x, strict))
3054
+               return true;
3055
+       // else if (zip_const_address_operand(x))
3056
+               // return true;
3057 202 dgisselq
+
3058 102 dgisselq
+       return false;
3059
+}
3060
+
3061
+static rtx
3062
+zip_legitimize_address(rtx x, rtx oldx ATTRIBUTE_UNUSED, machine_mode mode ATTRIBUTE_UNUSED) {
3063
+       ZIPDEBUGFLAG(dbg, false);
3064
+
3065
+
3066
+       if (dbg) zip_debug_rtx_pfx("LEGITIMIZE: ", x);
3067 202 dgisselq
+       if (zip_legitimate_address_p(mode, x, !can_create_pseudo_p()))
3068 102 dgisselq
+               return x;
3069
+
3070
+       if (dbg) zip_debug_rtx_pfx("ILLEGITIMATE: ", x);
3071
+       if (GET_CODE(x)==PLUS) {
3072
+               // if ((zip_legitimate_address_p(mode, XEXP(x,0),
3073 111 dgisselq
+               //              !can_create_pseudo_p()))
3074 102 dgisselq
+               //      &&(GETMODE(XEXP(x,1))==CONST_INT)) {
3075 111 dgisselq
+               //}
3076
+               if (!REG_P(XEXP(x,0)))
3077 102 dgisselq
+                       XEXP(x,0) = force_reg(Pmode,XEXP(x,0));
3078
+               if ((!zip_legitimate_address_p(mode, x, !can_create_pseudo_p()))
3079
+                       &&(!CONST_INT_P(XEXP(x,1))))
3080
+                       x = force_reg(GET_MODE(x),x);
3081 111 dgisselq
+       } else if (MEM_P(x))
3082
+               x = force_reg(GET_MODE(x),x);
3083 202 dgisselq
+
3084 111 dgisselq
+       if (dbg) zip_debug_rtx_pfx("LEGITIMATE: ", x);
3085 202 dgisselq
+       return x;
3086 111 dgisselq
+}
3087
+
3088
+void
3089
+zip_asm_output_def(FILE *stream, const char *name, const char *value)
3090 202 dgisselq
+{
3091 111 dgisselq
+       fprintf(stream, "\t.equ %s, %s\n", name, value);
3092 202 dgisselq
+}
3093
+
3094
+const char *zip_set_zero_or_one(rtx condition, rtx dst) {
3095
+       ZIPDEBUGFLAG(dbg, false);
3096 111 dgisselq
+
3097 202 dgisselq
+       if (dbg) fprintf(stderr, "ZIP::SET-ZERO-OR-ONE\n");
3098 111 dgisselq
+       if (dbg) zip_debug_rtx_pfx("CND", condition);
3099
+       if (dbg) zip_debug_rtx_pfx("REG", dst);
3100
+       switch(GET_CODE(condition)) {
3101
+       case EQ:        return "LDI\t0,%0\n\tLDILO.Z\t1,%0\t; set01_eq";
3102
+       case NE:        return "LDI\t0,%0\n\tLDILO.NZ\t1,%0\t; set01_ne";
3103
+       case LT:        return "LDI\t0,%0\n\tLDILO.LT\t1,%0\t; set01_lt";
3104
+       case GT:        return "LDI\t1,%0\n\tLDILO.LT\t1,%0\n\tLDILO.Z\t1,%0\t; set01_gt";
3105
+       case LE:        return "LDI\t0,%0\n\tLDILO.LT\t1,%0\n\tLDILO.Z\t1,%0\t; set01_le";
3106
+       case GE:        return "LDI\t0,%0\n\tLDILO.GE\t1,%0\t; set01_ge";
3107
+       case LTU:       return "LDI\t0,%0\n\tLDILO.C\t1,%0\t; set01_ltu";
3108 102 dgisselq
+       case GEU:       return "LDI\t0,%0\n\tLDILO.NC\t1,%0\t; set01_geu";
3109
+       case GTU:       return "LDI\t1,%0\n\tLDILO.C\t0,%0\n\tLDILO.Z\t0,%0\t; set01_gtu";
3110
+       case LEU:       return "LDI\t0,%0\n\tLDILO.C\t1,%0\n\tLDILO.Z\t1,%0\t; set01_leu";
3111 202 dgisselq
+       default:
3112 102 dgisselq
+               zip_debug_rtx(condition);
3113
+               internal_error("CSTORE Unsupported condition");
3114 202 dgisselq
+               return NULL;
3115
+       }
3116 102 dgisselq
+}
3117
+
3118
+int
3119
+zip_supported_condition(int c) {
3120
+       switch(c) {
3121 202 dgisselq
+       case EQ: case NE: case LT: case GE: case LTU: case GEU:
3122
+               return 1;
3123
+               break;
3124
+       default:
3125
+               break;
3126
+       } return 0;
3127
+}
3128
+
3129
+bool
3130
+zip_signed_comparison(int c) {
3131 102 dgisselq
+       switch(c) {
3132
+       case NE: case LT: case EQ: case GE:
3133
+               return true;
3134
+       default:
3135
+               break;
3136
+       } return false;
3137
+}
3138 200 dgisselq
+
3139 127 dgisselq
+int
3140
+zip_expand_movdi(rtx dst, rtx src) {
3141 202 dgisselq
+       ZIPDEBUGFLAG(dbg, false);
3142 200 dgisselq
+
3143 127 dgisselq
+       if (dbg) fprintf(stderr, "\nZIP::MOVDI\n");
3144
+       if (dbg) zip_debug_rtx_pfx("  DST", dst);
3145
+       if (dbg) zip_debug_rtx_pfx("  SRC", src);
3146 200 dgisselq
+
3147 102 dgisselq
+       // MOV !REG->!REG
3148
+       if ((!REG_P(dst))&&(!REG_P(src))&&(can_create_pseudo_p())) {
3149 127 dgisselq
+               // This includes:
3150
+               //      MOV MEM->MEM
3151
+               //      MOV IMM->MEM
3152 202 dgisselq
+               if (dbg) fprintf(stderr, "ZIP::MOVDI -- !REG->!REG\n");
3153 127 dgisselq
+
3154
+               rtx tmp = gen_reg_rtx(DImode);
3155
+               emit_insn(gen_movdi(tmp, src));
3156
+               emit_insn(gen_movdi(dst, tmp));
3157
+               return 1;
3158
+       }
3159 200 dgisselq
+
3160 202 dgisselq
+       // MOV REG->REG
3161
+       if ((REG_P(dst))&&(REG_P(src))) {
3162
+               if (dbg) fprintf(stderr, "ZIP::MOVDI -- REG->REG\n");
3163
+
3164 209 dgisselq
+               emit_insn(gen_movdi_raw(dst, src));
3165
+               return 1;
3166 127 dgisselq
+       }
3167 202 dgisselq
+
3168
+       // MOV SUBREG->REG
3169
+       if ((REG_P(dst))&&(SUBREG_P(src))) {
3170
+               if (dbg) fprintf(stderr, "ZIP::MOVDI -- SUBREG->REG\n");
3171
+
3172
+               if (GET_MODE(src)==DImode) {
3173 127 dgisselq
+                       emit_insn(gen_movdi_raw(dst, src));
3174 202 dgisselq
+                       return 1;
3175
+               }
3176
+       }
3177
+
3178 142 dgisselq
+       // MOV REG->SUBREG
3179
+       if ((SUBREG_P(dst))&&(REG_P(src))) {
3180 202 dgisselq
+               if (dbg) fprintf(stderr, "ZIP::MOVDI -- REG->SUBREG\n");
3181
+
3182
+               if (GET_MODE(dst)==DImode) {
3183 127 dgisselq
+                       emit_insn(gen_movdi_raw(dst, src));
3184 202 dgisselq
+                       return 1;
3185
+               }
3186
+       }
3187 127 dgisselq
+
3188 209 dgisselq
+       // MOV REG->MEM (a store instruction)
3189
+       if ((MEM_P(dst))&&(REG_P(src))) {
3190
+               rtx     addr = XEXP(dst,0);
3191
+               long    offset = 0;
3192
+               if ((GET_CODE(addr)==PLUS)&&(CONST_INT_P(XEXP(addr,1))))
3193
+                       offset = INTVAL(XEXP(addr,1));
3194
+
3195
+               if (dbg) fprintf(stderr, "ZIP::MOVDI -- REG->MEM\n");
3196
+               if (REG_P(addr)) {
3197
+                       emit_insn(gen_movdi_raw(dst, src));
3198
+                       return 1;
3199
+               } else if ((GET_CODE(addr)==PLUS)
3200
+                       &&(REG_P(XEXP(addr,0)))
3201
+                       &&(CONST_INT_P(XEXP(addr,1)))
3202
+                       &&(offset>=(long)zip_min_anchor_offset)
3203
+                       &&(offset+4<(long)zip_max_anchor_offset)) {
3204
+                       // Demonstrated and works
3205
+                       emit_insn(gen_movdi_raw(dst, src));
3206
+                       return 1;
3207
+               } else if (can_create_pseudo_p()) {
3208 202 dgisselq
+                       rtx tmp = gen_reg_rtx(Pmode);
3209
+                       emit_insn(gen_movsi(tmp, addr));
3210
+                       emit_insn(gen_movdi_raw(gen_rtx_MEM(DImode, tmp), src));
3211
+                       return 1;
3212
+               }
3213
+       }
3214 127 dgisselq
+
3215 202 dgisselq
+       // MOV MEM->REG (a load instruction)
3216
+       if ((REG_P(dst))&&(MEM_P(src))) {
3217
+               rtx addr = XEXP(src,0);
3218
+               long    offset = 0;
3219
+               if ((GET_CODE(addr)==PLUS)&&(CONST_INT_P(XEXP(addr,1))))
3220
+                       offset = INTVAL(XEXP(addr,1));
3221
+
3222
+               if (dbg) fprintf(stderr, "ZIP::MOVDI -- MEM->REG\n");
3223
+               if (REG_P(addr)) {
3224
+                       if (dbg) fprintf(stderr, "ZIP::MOVDI -- MEM[R]->REG\n");
3225
+                       emit_insn(gen_movdi_raw(dst, src));
3226
+                       return 1;
3227
+               } else if ((GET_CODE(addr)==PLUS)
3228
+                       &&(REG_P(XEXP(addr,0)))
3229
+                       &&(CONST_INT_P(XEXP(addr,1)))
3230
+                       &&(offset>=(long)zip_min_anchor_offset)
3231
+                       &&(offset+4<(long)zip_max_anchor_offset)) {
3232 102 dgisselq
+                       if (dbg) fprintf(stderr, "ZIP::MOVDI -- MEM[#+R]->REG -- DONE\n");
3233
+                       emit_insn(gen_movdi_raw(dst, src));
3234
+                       return 1;
3235 202 dgisselq
+               } else if (can_create_pseudo_p()) {
3236
+                       if (dbg) fprintf(stderr, "ZIP::MOVDI -- LDI #,R, MEM[R]->REG\n");
3237
+                       rtx tmp = gen_reg_rtx(Pmode);
3238
+                       emit_insn(gen_movsi(tmp, addr));
3239
+                       emit_insn(gen_movdi_raw(dst,
3240
+                               gen_rtx_MEM(DImode, tmp)));
3241 142 dgisselq
+                       return 1;
3242 202 dgisselq
+               } else if (dbg)
3243
+                       fprintf(stderr, "ZIP::MOVDI -- MEM[?]->REG (no match)\n");
3244
+       }
3245
+
3246
+       // MOV #->REG (An LDI instruction, but for DIwords)
3247
+       if ((CONST_INT_P(src))&&(REG_P(dst))) {
3248
+               if (dbg) fprintf(stderr, "ZIP::MOVDI -- IMM->REG\n");
3249
+               emit_insn(gen_movdi_raw(dst, src));
3250
+               return 1;
3251
+       }
3252
+
3253
+       return 0;
3254
+}
3255
+
3256
+const char *
3257
+zip_addsicc(rtx dst, rtx condition, rtx ifsrc, rtx addv) {
3258
+       // We know upon entry that REG_P(dst) must be true
3259
+       if (!REG_P(dst))
3260
+               internal_error("%s","ADDSICC into something other than register");
3261
+
3262
+       if ((REG_P(dst))&&(REG_P(ifsrc))&&(REG_P(addv))
3263
+               &&(REGNO(dst)!=REGNO(ifsrc))) {
3264 142 dgisselq
+               switch (GET_CODE(condition)) {
3265 127 dgisselq
+               case EQ: return "MOV.Z\t%2,%0\n\tADD.Z\t%3,%0";
3266 202 dgisselq
+               case NE: return "MOV.NZ\t%2,%0\n\tADD.NZ\t%3,%0";
3267
+               case LT: return "MOV.LT\t%2,%0\n\tADD.LT\t%3,%0";
3268
+
3269
+               case LE: return "MOV.LT\t%3,%0\n\tMOV.Z\t%3,%0\n\tADD.LT\t%3,%0\n\tADD.Z\t%3,%0";
3270
+               case GE: return "MOV.GE\t%2,%0\n\tADD.GE\t%3,%0";
3271 142 dgisselq
+
3272 127 dgisselq
+               case GT: return "BLT\t%.Laddsi%=\n\tBZ\t%%.Laddsi%=\n\tMOV\t%2,%0\n\tADD\t%3,%0\n.Laddsi%=:";
3273 202 dgisselq
+               case LTU: return "MOV.C\t%2,%0\n\tADD.C\t%3,%0";
3274
+
3275 142 dgisselq
+               case LEU: return "MOV.C\t%2,%0\n\tMOV.Z\t%2,%0\n\tADD.C\t%3,%0\n\tADD.Z\t%3,%0";
3276 202 dgisselq
+               case GEU: return "MOV.NC\t%2,%0\n\tADD.NC\t%3,%0";
3277
+               case GTU: return "BZ\t%.Laddsi%=\n\tMOV.NC\t%3,%0\n\tADD.NC\t%3,%0\n.Laddsi%=:";
3278
+               default:
3279
+                       internal_error("%s", "Zip/No usable addsi expansion");
3280
+                       break;
3281 127 dgisselq
+               }
3282 202 dgisselq
+       }
3283
+
3284
+       if ((REG_P(ifsrc))&&(REGNO(dst)==REGNO(ifsrc))) {
3285
+               switch (GET_CODE(condition)) {
3286
+               case EQ: return "ADD.Z\t%3,%0";
3287
+               case NE: return "ADD.NZ\t%3,%0";
3288 127 dgisselq
+               case LT: return "ADD.LT\t%3,%0";
3289 202 dgisselq
+               case LE: return "ADD.LT\t%3,%0\n\tADD.Z\t%3,%0";
3290
+               case GE: return "ADD.GE\t%3,%0";
3291 142 dgisselq
+               case GT: return "ADD.GE\t%3,%0\n\tSUB.Z\t%3,%0";
3292 202 dgisselq
+               case LTU: return "ADD.C\t%3,%0";
3293
+               case LEU: return "ADD.C\t%3,%0\n\tADD.Z\t%3,%0";
3294
+               case GEU: return "ADD.NC\t%3,%0";
3295
+               case GTU: return "SUB.Z\t%3,%0\n\tADD.NC\t%3,%0";
3296
+               default:
3297
+                       internal_error("%s", "Zip/No usable addsi expansion");
3298
+                       break;
3299
+               }
3300
+       } else {
3301
+               // MOV A+REG,REG
3302 142 dgisselq
+               switch (GET_CODE(condition)) {
3303
+               case EQ: return "MOV.Z\t%3+%2,%0";
3304 102 dgisselq
+               case NE: return "MOV.NZ\t%3+%2,%0";
3305
+               case LT: return "MOV.LT\t%3+%2,%0";
3306
+               case GT: return "BLT\t.Laddcc%=\n\tBZ\t.Laddcc%=\n\tMOV\t%3+%2,%0\n.Laddcc%=";
3307
+               case LE: return "MOV.LT\t%3+%2,%0\n\tMOV.Z\t%3+%2,%0";
3308
+               case GE: return "MOV.GE\t%3+%2,%0";
3309
+               case LTU: return "MOV.C\t%3+%2,%0";
3310
+               case LEU: return "MOV.C\t%3+%2,%0\n\tMOV.Z\t%3+%2,%0";
3311 202 dgisselq
+               case GEU: return "MOV.NC\t%3+%2,%0";
3312 102 dgisselq
+               case GTU: return "BZ\t.Laddcc%=\n\tMOV.NC\t%3+%2,%0\n\t.Laddcc%=:";
3313
+               default:
3314 202 dgisselq
+                       internal_error("%s", "Zip/No usable addsi(reg,reg) expansion");
3315
+                       break;
3316 102 dgisselq
+               }
3317
+       }
3318
+
3319
+       return "BREAK";
3320
+}
3321
+
3322
+static int     zip_memory_move_cost(machine_mode mode, reg_class_t ATTRIBUTE_UNUSED, bool in ATTRIBUTE_UNUSED) {
3323
+       int     rv = 14;
3324
+       if ((mode == DImode)||(mode == DFmode))
3325
+               rv += 2;
3326 202 dgisselq
+       return rv;
3327 102 dgisselq
+}
3328
+
3329
+// #warning "How do we tell the compiler LDI label is expensive as 2 ops"?
3330
+static bool    zip_cannot_modify_jumps_p(void) {
3331 202 dgisselq
+       // Let's try their suggested approach, keeping us from modifying jumps
3332
+       // after reload.  This should also allow our peephole2 optimizations
3333 102 dgisselq
+       // to adjust things back to what they need to be if necessary.
3334
+       return (reload_completed || reload_in_progress);
3335
+}
3336
+
3337
+rtx_insn       *zip_ifcvt_info;
3338
+
3339
+void
3340
+zip_ifcvt_modify_tests(ce_if_block *ce_info ATTRIBUTE_UNUSED, rtx *true_expr, rtx *false_expr) {
3341
+       const bool      dbg = ((ZIP_ALL_DEBUG_ON)||(false))&&(!ZIP_ALL_DEBUG_OFF);
3342 103 dgisselq
+       if (dbg) fprintf(stderr, "IFCVT-MODIFY-TESTS\n");
3343 102 dgisselq
+       if (*true_expr) switch(GET_CODE(*true_expr)) {
3344
+               // These are our unsupported conditions
3345
+               case LE:
3346
+               case GT:
3347
+               case LEU:
3348
+               case GTU:
3349 103 dgisselq
+                       if (dbg) fprintf(stderr, "TRUE, missing expr\n");
3350 117 dgisselq
+                       if (dbg) zip_debug_rtx(*true_expr);
3351
+                       *true_expr = NULL_RTX;
3352
+                       break;
3353
+               default: // LT, GT, GTE, LTU, NE, EQ
3354
+                       break;
3355
+       }
3356 122 dgisselq
+
3357
+       if (*false_expr) switch(GET_CODE(*false_expr)) {
3358
+               case LE:
3359
+               case GT:
3360
+               case LEU:
3361 202 dgisselq
+               case GTU:
3362 122 dgisselq
+                       if (dbg) fprintf(stderr, "FALSE, missing expr\n");
3363
+                       if (dbg) zip_debug_rtx(*false_expr);
3364 202 dgisselq
+                       *false_expr = NULL_RTX;
3365 122 dgisselq
+               default:
3366 202 dgisselq
+                       break;
3367
+       }
3368 122 dgisselq
+       if ((dbg)&&((!*true_expr)||(!*false_expr)))
3369
+               fprintf(stderr, "IFCVT-MODIFY-TESTS -- FAIL\n");
3370
+}
3371
+
3372
+void
3373
+zip_ifcvt_machdep_init(struct ce_if_block *ceinfo ATTRIBUTE_UNUSED) {
3374
+/*
3375
+if (!ceinfo->then_bb)
3376
+       return;
3377
+rtx_insn *insn;
3378
+FOR_BB_INSNS(ceinfo->then_bb, insn) {
3379 202 dgisselq
+       fprintf(stderr, "IFCVT -- INIT\n");
3380
+       zip_debug_rtx_pfx("INIT-BB", insn);
3381 122 dgisselq
+}
3382
+*/
3383
+/*
3384
+       zip_ifcvt_info = NULL;
3385
+       rtx_insn *insn, *ifinsn = NULL;
3386
+       FOR_BB_INSNS(ceinfo->test_bb, insn) {
3387
+               rtx     p;
3388
+               p = single_set(insn);
3389
+               if (!p) continue;
3390
+               if (SET_DEST(p)==pc_rtx) {
3391
+                       ifinsn = insn;
3392
+               }
3393 142 dgisselq
+               if (!REG_P(SET_DEST(p)))
3394 122 dgisselq
+                       continue;
3395 142 dgisselq
+               if (GET_MODE(SET_DEST(p))!=CCmode)
3396
+                       continue;
3397
+               if (REGNO(SET_DEST(p))!=zip_CC)
3398
+                       continue;
3399
+               zip_ifcvt_info = insn;
3400
+       }
3401 122 dgisselq
+
3402
+       if (zip_ifcvt_info)
3403
+               zip_debug_rtx_pfx("PUTATIVE-CMP",zip_ifcvt_info);
3404
+       if (ifinsn)
3405
+               zip_debug_rtx_pfx("PRIOR-JMP",ifinsn);
3406
+*/
3407
+}
3408
+
3409
+void
3410
+zip_ifcvt_modify_insn(struct ce_if_block *ceinfo ATTRIBUTE_UNUSED,
3411
+               rtx pattern ATTRIBUTE_UNUSED,
3412
+               rtx_insn *insn ATTRIBUTE_UNUSED) {
3413
+       // zip_debug_rtx_pfx("MODIFY-INSN: ", insn);
3414
+}
3415
+
3416
+void
3417
+zip_ifcvt_modify_cancel(struct ce_if_block *ceinfo ATTRIBUTE_UNUSED) {
3418
+/*
3419
+       fprintf(stderr, "IFCVT -- CANCEL\n");
3420
+       zip_ifcvt_info = NULL;
3421
+*/
3422
+}
3423
+
3424
+void
3425
+zip_ifcvt_modify_final(struct ce_if_block *ceinfo ATTRIBUTE_UNUSED) {
3426
+/*
3427
+rtx_insn *insn;
3428
+FOR_BB_INSNS(ceinfo->test_bb, insn) {
3429 142 dgisselq
+       fprintf(stderr, "IFCVT -- FINAL\n");
3430
+       zip_debug_rtx_pfx("FINAL-TEST-BB", insn);
3431
+}
3432
+       zip_ifcvt_info = NULL;
3433
+*/
3434
+}
3435
+
3436
+
3437
+int    zip_insn_sets_cc(rtx_insn *insn) {
3438
+       return (get_attr_ccresult(insn)==CCRESULT_SET);
3439
+}
3440
+
3441
+const char *
3442
+zip_cbranchdi_const(rtx comparison,
3443
+               rtx a ATTRIBUTE_UNUSED,
3444
+               rtx b,
3445
+               rtx label ATTRIBUTE_UNUSED) {
3446
+       gcc_assert(CONST_INT_P(b));
3447
+       long value = INTVAL(b);
3448
+
3449
+       // Look into the combine routines to find out why this routine never
3450
+       // gets called.
3451
+
3452
+       switch(GET_CODE(comparison)) {
3453
+       case EQ:
3454
+               if (value < 0)
3455
+                 return "CMP\t-1,%H1\t; cbranchdi/# EQ (neg)\n\tCMP.Z\t%2,%L1\n\tBZ\t%3";
3456
+               else
3457 127 dgisselq
+                 return "CMP\t0,%H1\t; cbranchdi/# EQ\n\tCMP.Z\t%2,%L1\n\tBZ\t%3";
3458
+       case NE:
3459
+               if (value < 0)
3460
+                 return "CMP\t-1,%H1\t; cbranchdi/# NE (neg)\n\tCMP.Z\t%2,%L1\n\tBNZ\t%3";
3461 202 dgisselq
+               else
3462
+                 return "CMP\t0,%H1\t; cbranchdi/# NE\n\tCMP.Z\t%2,%L1\n\tBNZ\t%3";
3463
+       case LE:
3464
+               if (value == 0)
3465
+                       return "CMP\t0,%H1\t; cbranchdi/# LE 0\n\tBLT\t%3\n\tCMP.Z\t0,%L1\n\tBZ\t%3";
3466
+               else if (value == -1)
3467
+                       return "CMP\t0,%H1\t; cbranchdi/# LE -1\n\tBLT\t%3";
3468
+               else if (value < 0) {
3469
+                       char    tmp[128];
3470
+                       sprintf(tmp, "CMP\t-1,%%H1\t; cbranchdi/# LE (neg)\n"
3471
+                               "\tBLT\t.Lcmpdile%%=\n"
3472
+                               "\tBNZ\t%%3\n"
3473
+                               "\tCMP\t%ld,%%L1\n"
3474
+                               "\tBC\t%%3", (value+1l)&0x0ffffffff);
3475
+                       return ggc_alloc_string(tmp, -1);
3476
+               } else { //; value > 0
3477
+                       char    tmp[128];
3478
+                       sprintf(tmp, "CMP\t0,%%H1\t; cbranchdi/# LE\n"
3479
+                               "\tBLT\t%%3\n"
3480
+                               "\tBNZ\t.Lcmple%%=\n"
3481
+                               "\tCMP\t%ld,%%L1\n"
3482
+                               "\tBC\t%%3\n"
3483
+                               ".Lcmple%%=:", value-1);
3484
+                       return ggc_alloc_string(tmp, -1);
3485
+               }
3486
+       case LT:
3487
+               if (value == 0)
3488
+                       return "CMP\t0,%H1\t; cbranchdi/# LT 0\n\tBLT\t%3";
3489
+               else if (value < 0)
3490
+                       return "CMP\t-1,%H1\t; cbranchdi/# LT neg\n\tCMP.Z\t%2,%L1\n\tBC\t%3";
3491
+               else
3492
+                       return "CMP\t0,%H1\t; cbranchdi/# LT\n"
3493
+                               "\tBLT\t%3\n"
3494
+                               "\tBNZ\t.Lcmplt%=\n"
3495
+                               "\tCMP\t%2,%L1\n"
3496
+                               "\tBC\t%3\n"
3497
+                               ".Lcmplt%=:";
3498
+       case GT:
3499
+               if (value == 0)
3500
+                       return "CMP\t1,%H1\t; cbranchdi/# GT 0\n"
3501
+                               "\tBGE\t%3\n"
3502
+                               "\tBNZ\t.Lcmpgt%=\n"
3503
+                               "\tCMP\t0,%L1\n"
3504
+                               "\tBNZ\t%3\n"
3505
+                               ".Lcmpgt%=:";
3506
+               else if (value == -1)
3507
+                       return "CMP\t0,%H1\t; cbranchdi/# GT -1\n"
3508
+                               "\tBGE\t%3\n";
3509
+               else if (value < 0) {
3510
+                       char    tmp[128];
3511
+                       sprintf(tmp, "CMP\t-1,%%H1\t; cbranchdi/# GT neg\n"
3512
+                               "\tBLT\t.Lcmpgt%%=\n"
3513
+                               "\tBNZ\t%%3\n"
3514
+                               "\tCMP\t%ld,%%H3\n"
3515
+                               "\tBNC\t%%3\n"
3516
+                               ".Lcmpgt%%=:", value+1l);
3517
+                       return ggc_alloc_string(tmp, -1);
3518
+               } else {
3519
+                       char    tmp[128];
3520
+                       sprintf(tmp, "CMP\t0,%%H1\t; cbranchdi/# GT\n"
3521
+                               "\tBLT\t.Lcmpgt%%=\n"
3522
+                               "\tBNZ\t%%3\n"
3523
+                               "\tCMP\t%ld,%%L1\n"
3524
+                               "\tBNC\t%%3\n"
3525
+                               ".Lcmpgt%%=:", value+1l);
3526
+                       return ggc_alloc_string(tmp, -1);
3527
+               }
3528
+       case GE:
3529
+               if (value == 0)
3530
+                       return "CMP\t0,%H1\t; cbranchdi/# GE 0\n"
3531
+                               "\tBLT\t.Lcmpge%=\n"
3532
+                               "\tBNZ\t%3\n"
3533
+                               "\tCMP\t0,%L1\n"
3534
+                               "\tBNC\t%3\n"
3535
+                               ".Lcmpge%=:";
3536
+               else if (value == -1)
3537
+                       return "CMP\t-1,%H1\t; cbranchdi/# GE -1\n"
3538
+                               "\tBLT\t.Lcmpge%=\n"
3539
+                               "\tBNZ\t%3\n"
3540
+                               "\tCMP\t-1,%L1\n"
3541
+                               "\tBZ\t%3\n"
3542
+                               ".Lcmpge%=:";
3543
+               else if (value < 0)
3544
+                       return "CMP\t-1,%H1\t; cbranchdi/# GE <\n"
3545
+                               "\tBLT\t.Lcmpge%=\n"
3546
+                               "\tBNZ\t%3\n"
3547
+                               "\tCMP\t%2,%L1\n"
3548
+                               "\tBNC\t%3\n"
3549
+                               ".Lcmpge%=:";
3550
+               else
3551
+                       return "CMP\t0,%H1\t; cbranchdi/# GE\n"
3552
+                               "\tBLT\t.Lcmpge%=\n"
3553
+                               "\tBNZ\t%3\n"
3554
+                               "\tCMP\t%2,%L1\n"
3555
+                               "\tBNC\t%3\n"
3556
+                               ".Lcmpge%=:";
3557
+       case LTU:
3558
+               if (value == 0) { //; Impossible, cannot be < 0 unsignd
3559
+                       return "; cbranchdi/# LTU 0 (Impossible!)";
3560
+               } else
3561
+                       return "CMP\t0,%H1\t; cbranchdi/#\n\tCMP.Z\t%2,%L1\n\tBC\t%3\n";
3562
+       case LEU:
3563
+               if (value == 0) { //; Only possible if == 0
3564
+                       return "CMP\t0,%%H0\t; cbranchdi/# LEU 0\n"
3565
+                               "\tCMP.Z\t0,%%L0\n"
3566
+                               "\tBZ\t%3";
3567
+               } else {
3568
+                       //; Subtract one, and LTU works
3569
+                       char    tmp[128];
3570
+                       sprintf(tmp, "CMP\t0,%%H1\t; cbranchdi/# LEU\n"
3571
+                               "\tCMP.Z\t%ld,%%L1\n"
3572
+                               "\tBC\t%%3\n", value-1);
3573
+                       return ggc_alloc_string(tmp, -1);
3574
+               }
3575
+       case GTU:
3576
+               if (value == 0) {
3577
+                       //; Equivalent to not equal to zero
3578
+                       return "CMP\t0,%H1\t; cbranchdi/# GTU 0\n\tCMP.Z\t0,%L1\n\tBNZ\t%3";
3579
+               } else {
3580
+                       char    tmp[128];
3581
+                       sprintf(tmp,
3582
+                               "CMP\t0,%%H1\t; cbranchdi/# GTU\n"
3583
+                               "\tBNZ\t%%3\n"
3584
+                               "\tCMP\t%ld,%%L1\n"
3585
+                               "\tBNC\t%%3\n", value+1);
3586
+                       return ggc_alloc_string(tmp, -1);
3587
+               }
3588
+       case GEU:
3589
+               if (value == 0) //; Unsigned, always true
3590
+                       return "BRA\t%3\t; cbranchdi/# GEU 0";
3591
+               else
3592
+                       return "CMP\t0,%H1\t; cbranchdi/# GEU\n"
3593
+                               "\tBNZ\t%3\n"
3594
+                               "\tCMP\t%2,%L1\n"
3595
+                               "\tBNC\t%3";
3596
+       default:
3597
+               gcc_unreachable();
3598
+       }
3599
+}
3600
+
3601
+const char *
3602
+zip_cbranchdi_reg(rtx comparison,
3603
+               rtx a ATTRIBUTE_UNUSED,
3604
+               rtx b ATTRIBUTE_UNUSED,
3605
+               rtx label ATTRIBUTE_UNUSED) {
3606
+
3607
+       switch(GET_CODE(comparison)) {
3608
+               case EQ:
3609
+                       return "CMP\t%H2,%H1\t; cbranchdi/r EQ\n\tCMP.Z\t%L2,%L1\n\tBZ\t%3";
3610
+               case NE:
3611
+                       return "CMP\t%H2,%H1\t; cbranchdi/r NE\n\tCMP.Z\t%L2,%L1\n\tBNZ\t%3";
3612
+               case LE:
3613
+                       return "CMP\t%H2,%H1\t; cbranchdi/r LE\n"
3614
+                               "\tBLT\t%3\n"
3615
+                               "\tBNZ\t.Ldi%=\n"
3616
+                               "\tCMP\t%L1,%L2\n"
3617
+                               "\tBNC\t%3\n"
3618
+                               ".Ldi%=:";
3619 127 dgisselq
+               case GT:
3620 202 dgisselq
+                       return "CMP\t%H1,%H2\t; cbranchdi/r GT\n"
3621
+                               "\tBLT\t%3\n"
3622
+                               "\tBNZ\t.Ldi%=\n"
3623
+                               "\tCMP\t%L1,%L2\n"
3624
+                               "\tBC\t%3\n"
3625
+                               ".Ldi%=:";
3626
+               case LT:
3627
+                       return "CMP\t%H2,%H1\t; cbranchdi/r LT\n"
3628
+                               "\tBLT\t%3\n"
3629
+                               "\tBNZ\t.Ldi%=\n"
3630
+                               "\tCMP\t%L2,%L1\n"
3631
+                               "\tBC\t%3\n"
3632
+                               ".Ldi%=:";
3633
+               case GE:
3634
+                       return "CMP\t%H1,%H2\t; cbranchdi/r GE\n"
3635
+                               "\tBLT\t%3\n"
3636
+                               "\tBNZ\t.Ldi%=\n"
3637
+                               "\tCMP\t%L2,%L1\n"
3638
+                               "\tBNC\t%3\n"
3639
+                               ".Ldi%=:";
3640
+               case LTU:
3641
+                       return "CMP\t%H2,%H1\t; cbranchdi/r LTU\n"
3642
+                               "\tCMP.Z\t%L2,%L1\n"
3643
+                               "\tBC\t%3\n";
3644
+               case LEU:
3645
+                       return "CMP\t%H1,%H2\t; cbranchdi/r LEU\n"
3646
+                               "\tBC\t.Ldi%=\n"        //; H1 > H2, skip
3647
+                               "\tCMP.Z\t%L1,%L2\n"    //; (H1==H2) test L1-L2
3648
+                               "\tBNC\t%3\n"           //; If (L1>=L2)||(H1>H2)
3649
+                               ".Ldi%=:";
3650
+               case GTU:
3651
+                       return "CMP\t%H1,%H2\t; cbranchdi/r GTU\n"
3652
+                               "\tCMP.Z\t%L1,%L2\n"
3653
+                               "\tBC\t%3";
3654
+               case GEU:
3655
+                       return "CMP\t%H2,%H1\t; cbranchdi/r GEU\n"
3656
+                               "\tBC\t.Ldi%=\n"
3657
+                               "\tCMP.Z\t%L2,%L1\n"
3658
+                               "\tBNC\t%3\n"
3659
+                               ".Ldi%=:";
3660
+               default:
3661
+                       gcc_unreachable();
3662
+       }
3663
+}
3664
+
3665
+const char *
3666
+zip_cbranchdi(rtx comparison, rtx a, rtx b, rtx label) {
3667
+       if (REG_P(b))
3668
+               return zip_cbranchdi_reg(comparison, a, b, label);
3669
+       else
3670
+               return zip_cbranchdi_const(comparison, a, b, label);
3671
+}
3672
+
3673
diff -Naur '--exclude=*.swp' gcc-6.2.0/gcc/config/zip/zipdbg.h gcc-6.2.0-zip/gcc/config/zip/zipdbg.h
3674
--- gcc-6.2.0/gcc/config/zip/zipdbg.h   1969-12-31 19:00:00.000000000 -0500
3675
+++ gcc-6.2.0-zip/gcc/config/zip/zipdbg.h       2017-02-17 16:47:25.727651898 -0500
3676
@@ -0,0 +1,8 @@
3677
+#define        DO_ZIP_DEBUGS
3678
+#ifdef DO_ZIP_DEBUGS
3679
+#include <stdio.h>
3680
+#define        ZIP_DEBUG_LINE(STR,RTX) do{fprintf(stderr,"%s:%d/%s\n",__FILE__,__LINE__,STR); zip_debug_rtx(RTX);} while(0)
3681
+extern void    zip_debug_rtx(const_rtx);
3682
+#else
3683
+#define        ZIP_DEBUG_LINE(STR,RTX)
3684
+#endif
3685
diff -Naur '--exclude=*.swp' gcc-6.2.0/gcc/config/zip/zip-di.md gcc-6.2.0-zip/gcc/config/zip/zip-di.md
3686
--- gcc-6.2.0/gcc/config/zip/zip-di.md  1969-12-31 19:00:00.000000000 -0500
3687
+++ gcc-6.2.0-zip/gcc/config/zip/zip-di.md      2018-06-05 18:57:29.386399718 -0400
3688
@@ -0,0 +1,548 @@
3689
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3690
+;;
3691
+;; Filename:   zip-di.md
3692
+;;
3693
+;; Project:    Zip CPU -- a small, lightweight, RISC CPU soft core
3694
+;;
3695
+;; Purpose:    This is the machine description of the Zip CPU as needed by the
3696
+;;             GNU compiler collection (GCC).  Specifically, this is the
3697
+;;     section of the description associated with 64-bit values and
3698
+;;     arithmetic.
3699
+;;
3700
+;;
3701
+;; Creator:    Dan Gisselquist, Ph.D.
3702
+;;             Gisselquist Technology, LLC
3703
+;;
3704
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3705
+;;
3706
+;; Copyright (C) 2015-2018, Gisselquist Technology, LLC
3707 209 dgisselq
+;;
3708
+;; This program is free software (firmware): you can redistribute it and/or
3709 202 dgisselq
+;; modify it under the terms of  the GNU General Public License as published
3710
+;; by the Free Software Foundation, either version 3 of the License, or (at
3711
+;; your option) any later version.
3712
+;;
3713
+;; This program is distributed in the hope that it will be useful, but WITHOUT
3714
+;; ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
3715
+;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
3716
+;; for more details.
3717
+;;
3718
+;; License:    GPL, v3, as defined and found on www.gnu.org,
3719
+;;             http://www.gnu.org/licenses/gpl.html
3720
+;;
3721
+;;
3722
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3723
+;;
3724
+;;
3725
+;
3726 209 dgisselq
+;
3727 202 dgisselq
+;
3728
+(define_expand "movdi"
3729
+       [(set (match_operand:DI 0 "nonimmediate_operand" "")
3730
+               (match_operand:DI 1 "general_operand" ""))]
3731
+       "(ZIP_HAS_DI)"
3732
+       {
3733
+               if (zip_expand_movdi(operands[0], operands[1]))
3734
+                       DONE;
3735
+               FAIL;
3736
+       }
3737
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unchanged")])
3738
+;
3739
+;
3740
+;
3741
+(define_insn "movdi_raw"
3742
+       [(set (match_operand:DI 0 "nonimmediate_operand" "=r,Q,r,r")
3743
+               (match_operand:DI 1 "general_operand" "r,r,Q,i"))]
3744
+       "(ZIP_HAS_DI)"
3745
+       {
3746
+               if ((REG_P(operands[0]))&&(REG_P(operands[1])))
3747
+                       return  "MOV %H1,%H0\t; MOV:DI\n\tMOV %L1,%L0";
3748
+               else if (MEM_P(operands[0]))    //; StoreDI
3749
+                       return  "SW %H1,%0\t; Store:DI\n\tSW %L1,4+%0";
3750
+               else if (MEM_P(operands[1])) {  //; LoadDI
3751
+                       //; Deal with the case of
3752
+                       //;     LOD (R0),R0
3753
+                       //;     LOD 4(R0),R1
3754
+                       //; By reversing the order of the operands, to
3755
+                       //;     LOD 4(R0),R1
3756
+                       //;     LOD (R0),R0
3757
+                       //; This isn't efficient, so let's do whatever we can to
3758
+                       //; avoid this, still ... if we do it, we can make it
3759
+                       //; work
3760
+                       rtx     address = XEXP(operands[1],0);
3761
+                       int     hazard = 0;
3762
+                       if ( (REG_P(address))
3763
+                               &&((REGNO(address))==(REGNO(operands[0]))) )
3764
+                               hazard = 1;
3765
+                       else if ( (PLUS == (GET_CODE(address)))
3766
+                               &&(REGNO(XEXP(address,0))==(REGNO(operands[0]))) )
3767
+                               hazard = 1;
3768
+                       if (hazard)
3769
+                               return  "LW 4+%1,%L0\t; Load:DI\n\tLW %1,%H0";
3770 209 dgisselq
+                       else
3771
+                               return  "LW %1,%H0\t; Load:DI\n\tLW 4+%1,%L0";
3772
+               } else if (CONST_INT_P(operands[1])) {
3773
+                       char    tmp[128];
3774
+                       HOST_WIDE_INT   v = INTVAL(operands[1]);
3775
+                       sprintf(tmp, "LDI\t0x%08x,%%H0\t; LDI #:DI,%%H0\n\tLDI\t0x%08x,%%L0",
3776
+                               (unsigned)(v>>32),
3777
+                               (unsigned)(v));
3778
+                       return ggc_alloc_string(tmp, -1);
3779
+               } else
3780
+                       gcc_unreachable();
3781
+       }
3782
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unchanged")])
3783
+;
3784
+;
3785
+;
3786
+; ADD
3787
+;
3788
+;
3789
+(define_insn "adddi3" ; Fastest/best instruction always goes first
3790
+       [(set (match_operand:DI 0 "register_operand" "=r")
3791
+               (plus:DI (match_operand:DI 1 "register_operand" "0")
3792
+                       (match_operand:DI 2 "register_operand" "r")))
3793 202 dgisselq
+       (clobber (reg:CC CC_REG))
3794
+       ]
3795
+       "(ZIP_HAS_DI)"
3796
+       "ADD    %L2,%L0\n\tADD.C\t1,%H0\n\tADD\t%H2,%H0"
3797
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unknown")])
3798
+;
3799
+;
3800
+;
3801
+; SUB
3802
+;
3803
+;
3804
+(define_insn "subdi3"
3805
+       [(set (match_operand:DI 0 "register_operand" "=r")
3806
+               (minus:DI (match_operand:DI 1 "register_operand" "0")
3807
+                       (match_operand:DI 2 "register_operand" "r")))
3808
+       (clobber (reg:CC CC_REG))
3809
+       ]
3810
+       "(ZIP_HAS_DI)"
3811
+       "SUB    %L2,%L0\n\tSUB.C\t1,%H0\n\tSUB\t%H2,%H0"
3812
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unknown")])
3813
+;
3814
+;
3815
+;
3816
+; AND
3817
+;
3818
+;
3819
+(define_insn "anddi3"
3820
+       [(set (match_operand:DI 0 "register_operand" "=r")
3821
+               (and:DI (match_operand:DI 1 "register_operand" "%0")
3822
+                       (match_operand:DI 2 "register_operand" "r")))
3823
+       (clobber (reg:CC CC_REG))
3824
+       ]
3825
+       "(ZIP_HAS_DI)"
3826
+       "AND    %L2,%L0\t; AND:DI\n\tAND\t%H2,%H0"
3827
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unknown")])
3828
+;
3829
+;
3830
+;
3831
+; iOR
3832
+;
3833
+;
3834
+(define_insn "iordi3"
3835
+       [(set (match_operand:DI 0 "register_operand" "=r")
3836
+               (ior:DI (match_operand:DI 1 "register_operand" "%0")
3837
+                       (match_operand:DI 2 "register_operand" "r")))
3838
+       (clobber (reg:CC CC_REG))
3839
+       ]
3840
+       "(ZIP_HAS_DI)"
3841
+       "OR     %L2,%L0\t; OR:DI\n\tOR\t%H2,%H0"
3842
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unknown")])
3843
+;
3844
+;
3845
+;
3846
+; XOR
3847
+;
3848
+;
3849
+(define_insn "xordi3"
3850
+       [(set (match_operand:DI 0 "register_operand" "=r")
3851
+               (xor:DI (match_operand:DI 1 "register_operand" "%0")
3852
+                       (match_operand:DI 2 "register_operand" "r")))
3853
+       (clobber (reg:CC CC_REG))
3854
+       ]
3855
+       "(ZIP_HAS_DI)"
3856
+       "XOR    %L2,%L0\t; XOR:DI\n\tXOR\t%H2,%H0"
3857
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unknown")])
3858
+;
3859
+;
3860
+; NEG
3861
+;
3862
+;
3863
+(define_insn "negdi2"
3864
+       [(set (match_operand:DI 0 "register_operand" "=r")
3865
+               (neg:DI (match_operand:DI 1 "register_operand" "0")))
3866
+       (clobber (reg:CC CC_REG))
3867
+       ]
3868
+       "(ZIP_HAS_DI)"
3869
+       "XOR    -1,%L0\t; NEG:DI\n\tXOR\t-1,%H0\n\tADD\t1,%L0\n\tADD.C\t1,%H0"
3870
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unknown")])
3871
+;
3872
+;
3873
+;
3874
+; ABS
3875
+;
3876
+;
3877
+(define_insn "absdi2"
3878
+       [(set (match_operand:DI 0 "register_operand" "=r")
3879
+               (abs:DI (match_operand:DI 1 "register_operand" "0")))
3880
+       (clobber (match_scratch:SI 2 "=r"))
3881
+       (clobber (reg:CC CC_REG))
3882
+       ]
3883
+       "(ZIP_HAS_DI)"
3884
+       "CLR    %2      ; ABSDI
3885
+       TEST    %H0
3886
+       LDILO.LT        1,%2
3887
+       XOR.LT  -1,%L0
3888
+       XOR.LT  -1,%H0
3889
+       ADD     %2,%L0
3890
+       ADD.C   1,%H0"
3891
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unknown")])
3892
+;
3893
+;
3894
+; NOT
3895
+;
3896
+;
3897
+(define_insn "one_cmpldi2"
3898
+       [(set (match_operand:DI 0 "register_operand" "=r")
3899
+               (not:DI (match_operand:DI 1 "register_operand" "0")))
3900
+       (clobber (reg:CC CC_REG))
3901
+       ]
3902
+       "(ZIP_HAS_DI)"
3903
+       "XOR    -1,%L0\t; NOT:DI\n\tXOR\t-1,%H0"
3904
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unknown")])
3905
+;
3906
+;
3907
+; Unsigned min/max
3908
+;
3909
+;
3910
+(define_insn "umindi3"
3911
+       [(set (match_operand:DI 0 "register_operand" "=r")
3912
+               (umin:DI (match_operand:DI 1 "register_operand" "%0")
3913
+                       (match_operand:DI 2 "register_operand" "r")))
3914
+       (clobber (reg:CC CC_REG))
3915
+       ]
3916
+       "(ZIP_HAS_DI)"
3917
+       "CMP    %H0,%H2 ; umin:DI
3918
+       CMP.Z   %L0,%L2
3919
+       MOV.C   %H2,%H0
3920
+       MOV.C   %L2,%L0"
3921
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unknown")])
3922
+(define_insn "umaxdi3"
3923
+       [(set (match_operand:DI 0 "register_operand" "=r")
3924
+               (umax:DI (match_operand:DI 1 "register_operand" "%0")
3925
+                       (match_operand:DI 2 "register_operand" "r")))
3926
+       (clobber (reg:CC CC_REG))
3927
+       ]
3928
+       "(ZIP_HAS_DI)"
3929
+       "CMP    %H2,%H0 ; umax:DI
3930
+       CMP.Z   %L2,%L0
3931
+       MOV.C   %H2,%H0
3932
+       MOV.C   %L2,%L0"
3933
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unknown")])
3934
+;
3935
+;
3936
+; Multiply
3937
+;
3938
+;
3939
+(define_expand "muldi3"
3940
+       [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3941
+               (mult:DI (match_operand:DI 1 "register_operand" "r")
3942
+                       (match_operand:DI 2 "register_operand" "r")))
3943
+       (clobber (match_dup 1))
3944
+       (clobber (match_dup 2))
3945
+       (clobber (match_scratch:SI 3 "=r"))
3946
+       (clobber (reg:CC CC_REG))])]
3947
+       "(ZIP_HAS_DI)")
3948
+;
3949
+(define_insn "muldi3_raw"
3950
+       [(set (match_operand:DI 0 "register_operand" "=r")
3951
+               (mult:DI (match_operand:DI 1 "register_operand" "r")
3952
+                       (match_operand:DI 2 "register_operand" "r")))
3953
+       (clobber (match_dup 1))
3954
+       (clobber (match_dup 2))
3955
+       (clobber (match_scratch:SI 3 "=r"))
3956
+       (clobber (reg:CC CC_REG))]
3957
+       "(ZIP_HAS_DI)"
3958
+       {
3959
+               int     regno[3];
3960
+               regno[0] = REGNO(operands[0]);
3961
+               regno[1] = REGNO(operands[1]);
3962
+               regno[2] = REGNO(operands[2]);
3963
+               //; We need to adjust what we are doing based upon which
3964
+               //; registers are in common.  We have a couple of cases:
3965
+               //;
3966
+               if ((regno[0] == regno[1])&&(regno[0] == regno[2])) {
3967
+                       //; RA = RA * RA
3968
+                       //;
3969
+                       //; (H0:L0) = (H0:L0) * (H0:L0)
3970
+                       //; (H0:L0) = (H0*2^32 + L0) * (H0 * 2^32 + L0)
3971
+                       //; (H0:L0) = (H0*H0*2^64 + (H0*L0+L0*H0)*2^32 + L0 *L0)
3972
+                       //;     = (H0*L0+L0*H1):(L0*L0)
3973
+                       //;    :L0  = LOPART(L0 * L0)
3974
+                       //;  H0     = HIPART(L0 * L0)
3975
+                       //;  H0    += LOPART(H0 * L0)
3976
+                       //;  H0    += LOPART(L0 * H0)
3977
+                       //;
3978
+                       //;  Rx = L0
3979
+                       //;  H0 *= L0  ( =   LOPART( HI * LO )
3980
+                       //;  H0 <<= 1  ( = 2*LOPART( HI * LO ) )
3981
+                       //;  Rx *= L0  ( =   HIPART( LO * LO )
3982
+                       //;  L0 *= L0  ( =   LOPART( LO * LO )
3983
+                       //;  H0 += Rx  ( = 2*LOPART( HI * LO ) + HIPART( LO *LO)
3984
+                       //;
3985
+                       return "; muldi3_raw/A (%H0:%L0) = (%H1:%L1) * (%H2:%L2)\n"
3986
+                               "\tMOV\t%L0,%3\n"
3987
+                               "\tMPY\t%L0,%H0\n"
3988
+                               "\tLSL\t1,%H0\n"
3989
+                               "\tMPYUHI\t%L0,%3\n"
3990
+                               "\tMPY\t%L0,%L0\n"
3991
+                               "\tADD\t%3,%H0";
3992
+               } else if ((regno[0] != regno[1])&&(regno[1] == regno[2])) {
3993
+                       //; RA = RB * RB
3994
+                       //;
3995
+                       //; (H0:L0) = (H1:L1) * (H1:L1)
3996
+                       //; (H0:L0) = (H1*2^32 + L1) * (H1 * 2^32 + L1)
3997
+                       //; (H0:L0) = (H1*H1*2^64 + (H1*L1+L1*H1)*2^32 + L1 * L1)
3998
+                       //;     = (H1*L1+L1*H1):(L1*L1)
3999
+                       //;    :L0  = LOPART(L1 * L1)
4000
+                       //;  H0     = HIPART(L1 * L1)
4001
+                       //;  H0    += LOPART(H1 * L1)
4002
+                       //;  H0    += LOPART(L1 * H1)
4003
+                       //;
4004
+                       //; -------------------
4005
+                       //;     L0  = L1
4006
+                       //;     L0  = LOPART(L0 * L1)
4007
+                       //;     H0  = H1
4008
+                       //;     H0  = LOPART(H0 * L1)
4009
+                       //;     H0 <<= 1;       i.e. *= 2
4010
+                       //;     L1  = HIPART(L1 * L1)
4011
+                       //;     H0 += L1
4012
+                       //;
4013
+                       return "; muldi3_raw/B (%H0:%L0) = (%H1:%L1) * (%H2:%L2)\n"
4014
+                       "\tMOV\t%L1,%L0\n"
4015
+                       "\tMPY\t%L1,%L0\n"
4016
+                       "\tMOV\t%H1,%H0\n"
4017
+                       "\tMPY\t%H1,%H0\n"
4018
+                       "\tLSL\t1,%H0\n"
4019
+                       "\tMPY\t%L1,%L1\n"
4020
+                       "\tADD\t%L2,%H0";
4021
+               } else if ((regno[0] == regno[1])&&(regno[1] != regno[2])) {
4022
+                       //; RA = RA * RB, with scratch Rx
4023
+                       //;
4024
+                       //; (H0:L0) = (H0:L0) * (H1:L1)
4025
+                       //; (H0:L0) = (H0*2^32 + L0) * (H1 * 2^32 + L1)
4026
+                       //; (H0:L0) = (H0*H1*2^64 + (H0*L1+L0*H1)*2^32 + L0 *L1)
4027
+                       //;     = (H0*L1+L0*H1):(L0*L1)
4028
+                       //;     Rx  = L0
4029
+                       //;    :L0  = LOPART(L1 * R0)
4030
+                       //;  H0     = LOPART(H0 * L1)
4031
+                       //;  H0    += H1 = LOPART(Rx * H1)
4032
+                       //;  H0    += HIPART(L1 * Rx)
4033
+                       //;
4034
+                       return "; muldi3_raw/C (%H0:%L0) = (%H1:%L1) * (%H2:%L2)\n"
4035
+                       "\tMOV\t%L0,%3\n"
4036
+                       "\tMPY\t%L1,%L0\n"
4037
+                       "\tMOV\t%L1,%H0\n"
4038
+                       "\tMPY\t%H1,%H0\n"
4039
+                       "\tMPY\t%3,%H1\n"
4040
+                       "\tADD\t%H1,%H0\n"
4041
+                       "\tMPY\t%3,%L1\n"
4042
+                       "\tADD\t%L1,%H0";
4043
+               } else {
4044
+                       //; RA = RB * RC
4045
+                       //;
4046
+                       //; (H0:L0) = (H1:L1) * (H2:L2)
4047
+                       //; (H0:L0) = (H1*2^32 + L1) * (H2 * 2^32 + L2)
4048
+                       //; (H0:L0) = (H1*H2*2^64 + (H1*L2+L1*H2)*2^32 + L1 *L2)
4049
+                       //;     = (H1*L2+L1*H2):(L1*L2)
4050
+                       //;    :L0  = LOPART(L1 * L2)
4051
+                       //;  H0     = HIPART(L1 * L2)
4052
+                       //;  H0    += LOPART(H1 * L2)
4053
+                       //;  H0    += LOPART(L1 * H2)
4054
+                       //;
4055
+                       //; We can re-order this to try to save some registers
4056
+                       //;
4057
+                       //;     H1 *= L0                // Was H1 * L2
4058
+                       //;    :L0  = LOPART(L1 * L2)
4059
+                       //;  H0     = LOPART(L1 * R1)
4060
+                       //;  H0    += HIPART(L1 * H2)
4061
+                       //;  H0    += H1
4062
+                       //;
4063
+                    return "; muldi3_raw/D (%H0:%L0) = (%H1:%L1) * (%H2:%L2)\n"
4064
+                       "\tMPY  %L2,%H1 ; H1 = H1 * L2\n"
4065
+                       "\tMPY  %L1,%H2 ; H2 = L1 * L2\n"
4066
+                       "\tMOV  %L2,%L0 ; H0:L0 = L1 * L2\n"
4067
+                       "\tMOV  %L2,%H0\n"
4068
+                       "\tMPY  %L1,%L0\n"
4069
+                       "\tMPYUHI       %L1,%H0\n"
4070
+                       "\tADD  %H2,%H0 ; H0 += (H2 = L1 * H2)\n"
4071
+                       "\tADD  %H1,%H0 ; H0 += (H1 = H1 * L2)";
4072
+               }
4073
+       }
4074
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unknown")])
4075
+;
4076
+;
4077
+; Still missing DI instructions for smin:DI, smax:DI, movdicc, adddicc,
4078
+;      div:di, divu:di (library routine)
4079
+;
4080
+;
4081
+;
4082
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4083
+;;
4084
+;; Conditional arithmetic instructions
4085
+;;
4086
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4087
+;
4088
+;
4089
+;
4090
+;
4091
+(define_insn "cstoredi4" ; Store 0 or 1 in %0 based on cmp between %2&%3
4092
+       [(set (match_operand:SI 0 "register_operand" "=r")
4093
+               (if_then_else:SI (match_operator 1 "ordered_comparison_operator"
4094
+                       [(match_operand:DI 2 "register_operand" "r")
4095
+                               (match_operand:DI 3 "register_operand" "r")])
4096
+                       (const_int 1) (const_int 0)))
4097
+       (clobber (reg:CC CC_REG))]
4098
+       "(ZIP_HAS_DI)&&(0)"
4099
+       {
4100
+               switch(GET_CODE(operands[1])) {
4101
+               case EQ:        return "CLR\t%0\t; CSTORE-EQ\n\tCMP\t%H3,%H2\n\tCMP.Z\t%L3,%L2\n\tLDILO.Z\t1,%0\n";
4102
+               case NE:        return "CLR\t%0\t; CSTORE-NE\n\tCMP\t%H3,%H2\n\tCMP.Z\t%L3,%L2\n\tLDILO.NZ\t1,%0\n";
4103
+               //; Missing LT
4104
+               //; Missing LE
4105
+               //; Missing GT
4106
+               //; Missing GE
4107
+               case LTU:       return "CLR\t%0\t; CSTORE-LTU\n\tCMP\t%H3,%H2\n\tCMP.Z\t%L3,%L2\n\tLDILO.C\t1,%0\n";
4108
+               case LEU:
4109
+                       return "CLR\t%0\t; CSTORE-LEU\n\tCMP\t%H2,%H3\n\tCMP.Z\t%L2,%L3\n\tLDILO.NC\t1,%0\n";
4110
+               case GTU:       return "CLR\t%0\t; CSTORE-GTU\n\tCMP\t%H2,%H3\n\tCMP.Z\t%L2,%L3\n\tLDILO.C\t1,%0\n";
4111
+               case GEU:
4112
+                       return "CLR\t%0\t; CSTORE-GEU\n\tCMP\t%H3,%H2\n\tCMP.Z\t%L3,%L2\n\tLDILO.NC\t1,%0\n";
4113
+               default:
4114
+                       gcc_unreachable();
4115
+               }
4116
+       }
4117
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unknown")])
4118
+;
4119
+;
4120
+;
4121
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4122
+;;
4123
+;; Comparison instructions, both compare and test
4124
+;;
4125
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4126
+;
4127
+;
4128
+;
4129
+(define_expand "cmpdi"
4130
+       [(set (reg:CC CC_REG) (compare:CC
4131
+               (match_operand:DI 0 "register_operand" "r")
4132
+               (match_operand:DI 1 "nonmemory_operand" "")))]
4133
+       ""
4134
+       {
4135
+               if (!REG_P(operands[1])) {
4136
+                       if (can_create_pseudo_p()) {
4137
+                               //; fprintf(stderr, "Generating pseudo register for compare\n");
4138
+                               rtx tmp = gen_reg_rtx(DImode);
4139
+                               emit_insn(gen_movdi(tmp,operands[1]));
4140
+                               operands[1] = tmp;
4141
+                               emit_insn(gen_cmpdi_reg(operands[0],tmp));
4142
+                               DONE;
4143
+                       } else FAIL;
4144
+               }
4145
+       })
4146
+(define_insn "cmpdi_reg"
4147
+       [(set (reg:CC CC_REG) (compare:CC
4148
+               (match_operand:SI 0 "register_operand" "r")
4149
+               (match_operand:SI 1 "register_operand" "r")))]
4150
+       ""
4151
+       "CMP\t%H1,%H0
4152
+       CMP.Z\t%L1,%L0"
4153
+       [(set_attr "ccresult" "set")])
4154
+;
4155
+;
4156
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4157
+;;
4158
+;; Conditional move instructions, since these won't accept conditional
4159
+;;     execution RTL
4160
+;;
4161
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4162
+;
4163
+(define_expand "cbranchdi4"
4164
+       [(set (pc) (if_then_else
4165
+               (match_operator 0 "ordered_comparison_operator"
4166
+                       [(match_operand:DI 1 "register_operand" "r")
4167
+                               (match_operand:DI 2 "nonimmediate_operand" "")])
4168
+                       (label_ref (match_operand 3 "" ""))
4169
+                       (pc)))
4170
+       (clobber (reg:CC CC_REG))]
4171
+       "(ZIP_HAS_DI)"
4172
+       {
4173
+               if (!REG_P(operands[2])) {
4174
+                       if ((CONST_INT_P(operands[2]))
4175
+                               &&(INTVAL(operands[2])> -(1l<<17))
4176
+                               &&(INTVAL(operands[2])<(1l<<17)-1)) {
4177
+                               emit_jump_insn(gen_cbranchdi4_internal(operands[0],
4178
+                                       operands[1], operands[2], operands[3]));
4179
+                               DONE;
4180
+                       } if (can_create_pseudo_p()) {
4181
+                               rtx tmp = gen_reg_rtx(DImode);
4182
+                               emit_insn(gen_movsi(tmp, operands[2]));
4183
+                               operands[2] = tmp;
4184
+                       }
4185
+               }
4186
+
4187
+               if (REG_P(operands[2])) {
4188
+                       emit_jump_insn(gen_cbranchdi4_internal(operands[0],
4189
+                               operands[1], operands[2], operands[3]));
4190
+                       DONE;
4191
+               }
4192
+       })
4193
+(define_insn "cbranchdi4_internal"
4194
+       [(set (pc) (if_then_else
4195
+               (match_operator 0 "ordered_comparison_operator"
4196
+                       [(match_operand:DI 1 "register_operand" "r,r,r")
4197
+                               (match_operand:DI 2 "nonmemory_operand" "K,x,r")])
4198
+                       (label_ref (match_operand 3 "" ""))
4199
+                       (pc)))
4200
+       (clobber (reg:CC CC_REG))]
4201
+       "(ZIP_HAS_DI)"
4202
+       {
4203
+               return zip_cbranchdi(operands[0], operands[1], operands[2], operands[3]);
4204
+       }
4205
+       [(set_attr "predicable" "no") (set_attr "ccresult" "unknown")])
4206
+;
4207
+;
4208
+;
4209
+;
4210
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4211
+;;
4212
+;; Unimplemented (or not yet implemented) RTL Codes
4213
+;;
4214
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4215
+;
4216
+;
4217
+;
4218
+;
4219
+;(define_insn "addvdi4"
4220
+;      )
4221
+;(define_insn "subvdi4"
4222
+;      )
4223
+;(define_insn "mulvdi4"
4224
+;      )
4225
+;(define_insn "umulvdi4"
4226
+;      )
4227
+;(define_insn "umulvdi4"
4228
+;      )
4229
+;(define_insn "negvdi3"
4230
+;      )
4231
+;
4232
+;(define_insn "maddsidi4"
4233
+;(define_insn "umaddsidi4"
4234
+;(define_insn "msubsidi4"
4235
+;(define_insn "umsubsidi4"
4236
+;
4237
diff -Naur '--exclude=*.swp' gcc-6.2.0/gcc/config/zip/zip-float.md gcc-6.2.0-zip/gcc/config/zip/zip-float.md
4238
--- gcc-6.2.0/gcc/config/zip/zip-float.md       1969-12-31 19:00:00.000000000 -0500
4239
+++ gcc-6.2.0-zip/gcc/config/zip/zip-float.md   2017-01-10 14:01:42.029341062 -0500
4240
@@ -0,0 +1,138 @@
4241
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4242
+;;
4243
+;; Filename:   zip-float.md
4244
+;;
4245
+;; Project:    Zip CPU -- a small, lightweight, RISC CPU soft core
4246
+;;
4247
+;; Purpose:    This is the machine description of the ZipCPU floating point
4248
+;;             unit (if installed).
4249
+;;
4250
+;;
4251
+;; Creator:    Dan Gisselquist, Ph.D.
4252
+;;             Gisselquist Technology, LLC
4253
+;;
4254
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4255
+;;
4256
+;; Copyright (C) 2015,2017, Gisselquist Technology, LLC
4257
+;;
4258
+;; This program is free software (firmware): you can redistribute it and/or
4259
+;; modify it under the terms of  the GNU General Public License as published
4260 200 dgisselq
+;; by the Free Software Foundation, either version 3 of the License, or (at
4261
+;; your option) any later version.
4262
+;;
4263
+;; This program is distributed in the hope that it will be useful, but WITHOUT
4264
+;; ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
4265
+;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
4266
+;; for more details.
4267
+;;
4268
+;; License:    GPL, v3, as defined and found on www.gnu.org,
4269
+;;             http://www.gnu.org/licenses/gpl.html
4270
+;;
4271
+;;
4272
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4273
+;;
4274
+;;
4275
+;
4276 202 dgisselq
+;
4277 200 dgisselq
+;
4278
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4279
+;;
4280
+;; Floating point Op-codes
4281
+;;
4282
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4283
+;
4284
+;
4285
+;
4286
+(define_insn "addsf3"
4287
+       [(set (match_operand:SF 0 "register_operand" "=r")
4288
+               (plus:SF (match_operand:SF 1 "register_operand" "0")
4289
+                       (match_operand:SF 2 "register_operand" "r")))
4290
+       (set (reg:CC CC_REG) (compare:CC (match_dup 0) (const_int 0)))]
4291
+       "(ZIP_FPU)"
4292
+       "FPADD  %2,%0"
4293
+       [(set_attr "ccresult" "unknown")])
4294
+(define_insn "subsf3"
4295
+       [(set (match_operand:SF 0 "register_operand" "=r")
4296
+               (minus:SF (match_operand:SF 1 "register_operand" "0")
4297
+                       (match_operand:SF 2 "register_operand" "r")))
4298
+       (set (reg:CC CC_REG) (compare:CC (match_dup 0) (const_int 0)))]
4299
+       "(ZIP_FPU)"
4300
+       "FPSUB  %2,%0"
4301
+       [(set_attr "ccresult" "unknown")])
4302
+(define_insn "mulsf3"
4303
+       [(set (match_operand:SF 0 "register_operand" "=r")
4304
+               (mult:SF (match_operand:SF 1 "register_operand" "0")
4305
+                       (match_operand:SF 2 "register_operand" "r")))
4306
+       (set (reg:CC CC_REG) (compare:CC (match_dup 0) (const_int 0)))]
4307
+       "(ZIP_FPU)"
4308
+       "FPMUL  %2,%0"
4309
+       [(set_attr "ccresult" "unknown")])
4310
+(define_insn "divsf3"
4311
+       [(set (match_operand:SF 0 "register_operand" "=r")
4312
+               (div:SF (match_operand:SF 1 "register_operand" "0")
4313
+                       (match_operand:SF 2 "register_operand" "r")))
4314