1 ; @(#)smartmac.h	1.2 90/10/14 20:56:14, AMD
2 ; start of smartmac.h file
3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4 ; Copyright 1988, 1989, 1990 Advanced Micro Devices, Inc.
5 ;
6 ; This software is the property of Advanced Micro Devices, Inc  (AMD)  which
7 ; specifically  grants the user the right to modify, use and distribute this
8 ; software provided this notice is not removed or altered.  All other rights
9 ; are reserved by AMD.
10 ;
11 ; AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS
12 ; SOFTWARE.  IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL
13 ; DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR
14 ; USE OF THIS SOFTWARE.
15 ;
16 ; So that all may benefit from your experience, please report  any  problems
17 ; or  suggestions about this software to the 29K Technical Support Center at
18 ; 800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131  in  the  UK,  or
19 ; 0031-11-1129 in Japan, toll free.  The direct dial number is 512-462-4118.
20 ;
21 ; Advanced Micro Devices, Inc.
22 ; 29K Support Products
23 ; Mail Stop 573
24 ; 5900 E. Ben White Blvd.
25 ; Austin, TX 78741
26 ; 800-292-9263
27 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28 ;
29 ;
30   .title "AM29000 Smart Macro Package"
31 ;
32 ;    Floating point package for AMD 29000 family
33 ;
34 ;    Copyright 1988 Advanced Micro Devices, Inc.
35 ;
36 ;    All rights reserved
37 ;
38 ;    Developed for AMD by Quantitative Technology Corporation
39 ;                         8700 SW Creekside Place Suite D
40 ;                         Beaverton OR 97005
41 ;                         (503) 626-3081
42 ;
43 ;    Version information :
44 ;
45 ;        Version 1.0 - 1 June 1988   - Larry Westerman (smart_macros.h)
46 ;
47 ; Revision 1.4  89/02/01  18:26:03  jimh
48 ; Changed to relect the new symbols from Bob Perlman, and the new include file.s
49 ;
50 ; Revision 1.3  89/01/31  10:13:34  jimh
51 ; Updated to use symbols from Bob Perlmans fpsymbol.h file.  This is
52 ; an extensive change.
53 ;
54 ; Revision 1.2  89/01/26  09:23:50  jimh
55 ; This version checked in previous to substituting Bob Perlman's floating
56 ; point symbols.
57 ;
58 ; Revision 1.1  89/01/24  13:23:29  jim
59 ; Initial revision
60 ; Replaces smart_macros.h ver 1.11.
61 ;
62 ;
63 ;
64 ;
65 ;  NOTES:
66 ;
67 ;    This package makes the following assumptions about the use of these
68 ;    smart macros:
69 ;
70 ;      1.  These macros will be after the entry code for a transcendental
71 ;          routine.  This entry code will move the original function arguments
72 ;          (by value, if the target language is FORTRAN) into the global
73 ;          registers t0/t1 and t2/t3 (t0 and t2 for single precision
74 ;          routines).
75 ;      2.  The sources of all operands will be one register from the
76 ;          following list:
77 ;            t0 or  t2  - the source is one of the original input operands
78 ;            rtn0       - the source is rtn0, which should be used as the
79 ;                         source for all constant values to be sent to the
80 ;                         AM29027 (when used)
81 ;            FP0 - FP7  - the source is one of the fp registers
82 ;      3.  The destination of all operations will be a register from the
83 ;          following list:
84 ;            rtn0       - the destination is the function return value
85 ;            FP0 - FP7  - the destination is one of the fp registers
86 ;      4.  The additional registers available for temporary use are
87 ;          t4, lrp, and slp.
88 ;
89 ;    These register definitions are all taken from the file "proregs.a"
90 ;    which was supplied by AMD.  NOTE that the FP0-FP7 registers, for the
91 ;    Am29000 version of the file, overlap with the rtn0-rtn15 registers, so
92 ;    that FP0 corresponds to rtn0/rtn1, FP1 to rtn2/rtn3, and so forth.
93 ;
94  .equ ERROR,0
95  .equ NO_ERROR,1
96 
97  .equ DOUBLE_FUNCTION,0
98  .equ SINGLE_FUNCTION,1
99 
100  .equ T_OPERATION,0
101  .equ Q_OPERATION,1
102 
103  .equ R_SOURCE_29000,0
104  .equ R_SOURCE_29027,1
105 
106  .equ S_SOURCE_29000,0
107  .equ S_SOURCE_29027,1
108 
109  .equ DESTINATION_29000, 0
110  .equ DESTINATION_29027, 1
111 
112 ;
113 ; SMART MACRO : mfadd
114 ;
115 ; FUNCTION : single-precision floating point addition
116 ;
117 ; Required arguments : destination - one of possible destinations
118 ;                      operand1    - one of possible sources
119 ;                      operand2    - one of possible sources
120 ;
121  .macro mfadd,destination,operand1,operand2
122 
123    .if $narg!=3
124      .err
125      .print "mfadd: missing parameter(s)"
126      .exitm
127    .endif
128 
129    .ifdef _29027_MODE
130   ;
131   ; For 29027 mode, perform full suite of checking
132   ;
133      initialize_previous_instruction
134      .set CURRENT_INSTRUCTION, CP_S_S | CP_P_PLUS_T
135      .set OPERATION_TYPE, T_OPERATION
136      perform_single_operation destination,operand1,operand2
137      read_single_result destination
138     ;
139     ; Save the instruction for the next macro invocation
140     ;
141      .set PREVIOUS_INSTRUCTION, CURRENT_INSTRUCTION
142 
143    .else
144   ;
145   ; For 29000 mode, simply produce equivalent trap-inducing instruction
146   ;
147      fadd destination,operand1,operand2
148 
149    .endif
150 
151  .endm        ; end of mfadd macro definition
152 
153 ;
154 ; SMART MACRO : mfsub
155 ;
156 ; FUNCTION : single-precision floating point subtraction
157 ;
158 ; Required arguments : destination - one of possible destinations
159 ;                      operand1    - one of possible sources
160 ;                      operand2    - one of possible sources
161 ;
162  .macro mfsub,destination,operand1,operand2
163 
164    .if $narg!=3
165      .err
166      .print "mfsub: missing parameter(s)"
167      .exitm
168    .endif
169 
170    .ifdef _29027_MODE
171   ;
172   ; For 29027 mode, perform full suite of checking
173   ;
174      initialize_previous_instruction
175      .set CURRENT_INSTRUCTION, CP_S_S | CP_P_MINUS_T
176      .set OPERATION_TYPE, T_OPERATION
177      perform_single_operation destination,operand1,operand2
178      read_single_result destination
179     ;
180     ; Save the instruction for the next macro invocation
181     ;
182      .set PREVIOUS_INSTRUCTION, CURRENT_INSTRUCTION
183 
184    .else
185   ;
186   ; For 29000 mode, simply produce equivalent trap-inducing instruction
187   ;
188      fsub destination,operand1,operand2
189 
190    .endif
191 
192  .endm        ; end of mfsub macro definition
193 
194 ;
195 ; SMART MACRO : mfmul
196 ;
197 ; FUNCTION : single-precision floating point multiplication
198 ;
199 ; Required arguments : destination - one of possible destinations
200 ;                      operand1    - one of possible sources
201 ;                      operand2    - one of possible sources
202 ;
203  .macro mfmul,destination,operand1,operand2
204 
205    .if $narg!=3
206      .err
207      .print "mfmul: missing parameter(s)"
208      .exitm
209    .endif
210 
211    .ifdef _29027_MODE
212   ;
213   ; For 29027 mode, perform full suite of checking
214   ;
215      initialize_previous_instruction
216      .set CURRENT_INSTRUCTION, CP_S_S | CP_P_TIMES_Q
217      .set OPERATION_TYPE, Q_OPERATION
218      perform_single_operation destination,operand1,operand2
219      read_single_result destination
220     ;
221     ; Save the instruction for the next macro invocation
222     ;
223      .set PREVIOUS_INSTRUCTION, CURRENT_INSTRUCTION
224 
225    .else
226   ;
227   ; For 29000 mode, simply produce equivalent trap-inducing instruction
228   ;
229      fmul destination,operand1,operand2
230 
231    .endif
232 
233  .endm        ; end of mfmul macro definition
234 
235 ;
236 ; SMART MACRO : mfdiv
237 ;
238 ; FUNCTION : single-precision floating point divide
239 ;
240 ; Required arguments : destination - one of possible destinations
241 ;                      operand1    - one of possible sources
242 ;                      operand2    - one of possible sources
243 ;
244  .macro mfdiv,destination,operand1,operand2
245 
246    .if $narg!=3
247      .err
248      .print "mfdiv: missing parameter(s)"
249      .exitm
250    .endif
251 
252   ;
253   ; Generate the trap instruction in all cases
254   ;
255    fdiv destination, operand1, operand2
256 
257  .endm        ; end of mfdiv macro definition
258 
259 
260 ;
261 ; SMART MACRO : mdadd
262 ;
263 ; FUNCTION : double-precision floating point addition
264 ;
265 ; Required arguments : destination - one of possible destinations
266 ;                      operand1    - one of possible sources
267 ;                      operand2    - one of possible sources
268 ;
269  .macro mdadd,destination,operand1,operand2
270 
271    .if $narg!=3
272      .err
273      .print "mdadd: missing parameter(s)"
274      .exitm
275    .endif
276 
277    .ifdef _29027_MODE
278   ;
279   ; For 29027 mode, perform full suite of checking
280   ;
281      initialize_previous_instruction
282      .set CURRENT_INSTRUCTION, CP_D_D | CP_P_PLUS_T
283      .set OPERATION_TYPE, T_OPERATION
284      perform_double_operation destination,operand1,operand2
285      read_double_result destination
286     ;
287     ; Save the instruction for the next macro invocation
288     ;
289      .set PREVIOUS_INSTRUCTION, CURRENT_INSTRUCTION
290 
291    .else
292   ;
293   ; For 29000 mode, simply produce equivalent trap-inducing instruction
294   ;
295      dadd destination,operand1,operand2
296 
297    .endif
298 
299  .endm        ; end of mdadd macro definition
300 
301 ;
302 ; SMART MACRO : mdsub
303 ;
304 ; FUNCTION : double-precision floating point subtraction
305 ;
306 ; Required arguments : destination - one of possible destinations
307 ;                      operand1    - one of possible sources
308 ;                      operand2    - one of possible sources
309 ;
310  .macro mdsub,destination,operand1,operand2
311 
312    .if $narg!=3
313      .err
314      .print "mdsub: missing parameter(s)"
315      .exitm
316    .endif
317 
318    .ifdef _29027_MODE
319   ;
320   ; For 29027 mode, perform full suite of checking
321   ;
322      initialize_previous_instruction
323      .set CURRENT_INSTRUCTION, CP_D_D | CP_P_MINUS_T
324      .set OPERATION_TYPE, T_OPERATION
325      perform_double_operation destination,operand1,operand2
326      read_double_result destination
327     ;
328     ; Save the instruction for the next macro invocation
329     ;
330      .set PREVIOUS_INSTRUCTION, CURRENT_INSTRUCTION
331 
332    .else
333   ;
334   ; For 29000 mode, simply produce equivalent trap-inducing instruction
335   ;
336      dsub destination,operand1,operand2
337 
338    .endif
339 
340  .endm        ; end of mdsub macro definition
341 
342 ;
343 ; SMART MACRO : mdmul
344 ;
345 ; FUNCTION : double-precision floating point multiplication
346 ;
347 ; Required arguments : destination - one of possible destinations
348 ;                      operand1    - one of possible sources
349 ;                      operand2    - one of possible sources
350 ;
351  .macro mdmul,destination,operand1,operand2
352 
353    .if $narg!=3
354      .err
355      .print "mdmul: missing parameter(s)"
356      .exitm
357    .endif
358 
359    .ifdef _29027_MODE
360  ;
361  ; For 29027 mode, perform full suite of checking
362  ;
363      initialize_previous_instruction
364      .set CURRENT_INSTRUCTION, CP_D_D | CP_P_TIMES_Q
365      .set OPERATION_TYPE, Q_OPERATION
366      perform_double_operation destination,operand1,operand2
367      read_double_result destination
368    ;
369    ; Save the instruction for the next macro invocation
370    ;
371      .set PREVIOUS_INSTRUCTION, CURRENT_INSTRUCTION
372 
373    .else
374  ;
375  ; For 29000 mode, simply produce equivalent trap-inducing instruction
376  ;
377      dmul destination,operand1,operand2
378 
379    .endif
380 
381  .endm        ; end of mdmul macro definition
382 
383 ;
384 ; SMART MACRO : mddiv
385 ;
386 ; FUNCTION : double-precision floating point divide
387 ;
388 ; Required arguments : destination - one of possible destinations
389 ;                      operand1    - one of possible sources
390 ;                      operand2    - one of possible sources
391 ;
392  .macro mddiv,destination,operand1,operand2
393 
394    .if $narg!=3
395      .err
396      .print "mddiv: missing parameter(s)"
397      .exitm
398    .endif
399 
400  ;
401  ; Generate the trap instruction in all cases
402  ;
403    ddiv destination, operand1, operand2
404 
405  .endm        ; end of mfdiv macro definition
406 
407 ;
408 ;  SMART MACRO: mconvert
409 ;
410 ;  FUNCTION: Floating point/integer conversion
411 ;
412 ;  PARAMETERS:  destination           -  one of the possible destinations
413 ;               source                -  one of the possible sources
414 ;               sign_flag             -  one of SIGNED or UNSIGNED
415 ;               rounding_mode         -  one of ROUND_TO_NEAREST, ROUND_TO_PLUS,
416 ;                                         ROUND_TO_MINUS, ROUND_TO_ZERO
417 ;               destination_precision -  one of FORMAT_INTEGER, FORMAT_DOUBLE,
418 ;                                         or FORMAT_SINGLE
419 ;               source_precision      -  one of FORMAT_INTEGER, FORMAT_DOUBLE,
420 ;                                         or FORMAT_SINGLE
421 ;
422  .macro mconvert, destination, source, sign_flag, rounding_mode, destination_precision, source_precision
423 
424    .if $narg!=6
425      .err
426      .print "mconvert: missing parameter(s)"
427      .exitm
428    .endif
429 
430    .ifdef _29027_MODE
431   ;
432   ; Generate in line 29027 code
433   ;
434      initialize_previous_instruction
435      .if ( destination_precision == FORMAT_INTEGER )
436        .set CURRENT_INSTRUCTION, CP_CONVERT_T_TO_INT
437        select_T_operand source
438        .if ( source_precision == FORMAT_DOUBLE )
439          .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_S_D
440        .else
441          .if ( source_precision == FORMAT_SINGLE )
442            .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_S_S
443          .else
444            .err
445            .print "mconvert: invalid source type"
446            .exitm
447          .endif
448        .endif
449      .else
450        .if ( destination_precision == FORMAT_DOUBLE )
451          .if ( source_precision == FORMAT_SINGLE )
452            .set CURRENT_INSTRUCTION, CP_PASS_P | CP_P_EQ_R | CP_D_S
453            select_P_operand source
454          .else
455            .if ( source_precision == FORMAT_INTEGER )
456              .set CURRENT_INSTRUCTION, CP_I_CONVERT_T_TO_FLOAT | CP_D_S
457              select_T_operand source
458            .else
459              .err
460              .print "mconvert: invalid source type"
461              .exitm
462            .endif
463          .endif
464        .else
465          .if ( destination_precision == FORMAT_SINGLE )
466            .if ( source_precision == FORMAT_DOUBLE )
467              .set CURRENT_INSTRUCTION, CP_PASS_P | CP_P_EQ_R | CP_S_D
468              select_P_operand source
469            .else
470              .if ( source_precision == FORMAT_INTEGER )
471                .set CURRENT_INSTRUCTION, CP_I_CONVERT_T_TO_FLOAT | CP_S_S
472                select_T_operand source
473              .else
474                .err
475                .print "mconvert: invalid source type"
476                .exitm
477              .endif
478            .endif
479          .else
480            .err
481            .print "mconvert: invalid destination type "
482            .exitm
483          .endif
484        .endif
485      .endif
486     ;
487     ; Perform the operation, using a 29027 dummy register as the second
488     ; source operand, to avoid writing any data inappropriately to the
489     ; 29027
490     ;
491      select_destination destination
492      .set S_SOURCE, S_SOURCE_29027
493      .if ( source_precision == FORMAT_DOUBLE )
494        write_and_execute_double_operation source, FP0
495      .else
496        write_and_execute_single_operation source, FP0
497      .endif
498      .if ( destination_precision == FORMAT_DOUBLE )
499        read_double_result destination
500      .else
501        .if ( destination_precision == FORMAT_SINGLE )
502          read_single_result destination
503        .else
504          read_integer_result destination
505        .endif
506      .endif
507    .else
508   ;
509   ; For 29000 mode (the default) just invoke the trap-inducing instruction
510   ;
511      convert destination,source,sign_flag,rounding_mode,destination_precision,source_precision
512 
513    .endif
514 
515  .endm       ; end of mfeq macro definition
516 
517 ;
518 ;  SMART MACRO: mfeq
519 ;
520 ;  FUNCTION: Single precision, floating point compare
521 ;
522 ;  PARAMETERS:  destination  -  one of the possible destinations
523 ;               operand1     -  one of the possible sources
524 ;               operand2     -  one of the possible sources
525 ;
526  .macro mfeq, destination, operand1, operand2
527 
528    .if $narg!=3
529      .err
530      .print "mfeq: missing parameter(s)"
531      .exitm
532    .endif
533 
534    .ifdef _29027_MODE
535   ;
536   ; Generate in line 29027 code
537   ;
538      initialize_previous_instruction
539      .set CURRENT_INSTRUCTION, CP_S_S  | CP_COMPARE_P_AND_T
540      .set OPERATION_TYPE,  T_OPERATION
541      select_destination destination
542     ;
543     ; 29027 registers are not valid destinations for compare operations
544     ; If the destination is a 29000 register, write the appropriate
545     ; Boolean value to that register.
546     ;
547      .if ( DESTINATION == DESTINATION_29027 )
548        .err
549        .print "29027 destinations invalid for compares - @destination@"
550        .exitm
551      .else
552        perform_single_operation destination, operand1, operand2
553        cp_read_flags destination
554        srl  destination,  destination, CP_EQUAL_FLAG_POSITION
555        sll  destination,  destination,  31
556      .endif
557 
558    .else
559   ;
560   ; For 29000 mode (the default) just invoke the trap-inducing instruction
561   ;
562      feq destination,operand1,operand2
563 
564    .endif
565 
566  .endm       ; end of mfeq macro definition
567 
568 ;
569 ;  SMART MACRO: mfge
570 ;
571 ;  FUNCTION: Single precision, floating point compare
572 ;
573 ;  PARAMETERS:  destination  -  one of the possible destinations
574 ;               operand1     -  one of the possible sources
575 ;               operand2     -  one of the possible sources
576 ;
577  .macro mfge, destination, operand1, operand2
578 
579    .if $narg!=3
580      .err
581      .print "mfge: missing parameter(s)"
582      .exitm
583    .endif
584 
585    .ifdef _29027_MODE
586   ;
587   ; Generate in line 29027 code
588   ;
589      initialize_previous_instruction
590      .set CURRENT_INSTRUCTION, CP_S_S  | CP_COMPARE_P_AND_T
591      .set OPERATION_TYPE,  T_OPERATION
592      select_destination destination
593     ;
594     ; 29027 registers are not valid destinations for compare operations
595     ; If the destination is a 29000 register, write the appropriate
596     ; Boolean value to that register.
597     ;
598      .if ( DESTINATION == DESTINATION_29027 )
599        .err
600        .print "29027 destinations invalid for compares - @destination@"
601        .exitm
602      .else
603         perform_single_operation destination, operand1, operand2
604         cp_read_flags destination
605         and   destination, destination, CP_EQUAL_FLAG | CP_GREATER_THAN_FLAG
606         cpneq destination, destination, 0x0
607      .endif
608 
609    .else
610   ;
611   ; For 29000 mode (the default) just invoke the trap-inducing instruction
612   ;
613      fge destination,operand1,operand2
614 
615    .endif
616 
617  .endm       ; end of mfge macro definition
618 
619 ;
620 ;  SMART MACRO: mfgt
621 ;
622 ;  FUNCTION: Single precision, floating point compare
623 ;
624 ;  PARAMETERS:  destination  -  one of the possible destinations
625 ;               operand1     -  one of the possible sources
626 ;               operand2     -  one of the possible sources
627 ;
628  .macro mfgt, destination, operand1, operand2
629 
630    .if $narg!=3
631      .err
632      .print "mfgt: missing parameter(s)"
633      .exitm
634    .endif
635 
636    .ifdef _29027_MODE
637   ;
638   ; Generate in line 29027 code
639   ;
640      initialize_previous_instruction
641      .set CURRENT_INSTRUCTION, CP_S_S  | CP_COMPARE_P_AND_T
642      .set OPERATION_TYPE,  T_OPERATION
643      select_destination destination
644     ;
645     ; 29027 registers are not valid destinations for compare operations
646     ; If the destination is a 29000 register, write the appropriate
647     ; Boolean value to that register.
648     ;
649      .if ( DESTINATION == DESTINATION_29027 )
650        .err
651        .print "29027 destinations invalid for compares - @destination@"
652        .exitm
653      .else
654         perform_single_operation destination, operand1, operand2
655         cp_read_flags destination
656         srl  destination,  destination, CP_GREATER_THAN_FLAG_POSITION
657         sll  destination,  destination,  31
658      .endif
659 
660    .else
661   ;
662   ; For 29000 mode (the default) just invoke the trap-inducing instruction
663   ;
664      fgt destination,operand1,operand2
665 
666    .endif
667 
668  .endm       ; end of mfgt macro definition
669 
670 ;
671 ;  SMART MACRO: mdeq
672 ;
673 ;  FUNCTION: Double precision, floating point compare
674 ;
675 ;  PARAMETERS:  destination  -  one of the possible destinations
676 ;               operand1     -  one of the possible sources
677 ;               operand2     -  one of the possible sources
678 ;
679  .macro mdeq, destination, operand1, operand2
680 
681    .if $narg!=3
682      .err
683      .print "mdeq: missing parameter(s)"
684      .exitm
685    .endif
686 
687 
688    .ifdef _29027_MODE
689   ;
690   ; Generate in line 29027 code
691   ;
692      initialize_previous_instruction
693      .set CURRENT_INSTRUCTION, CP_D_D  | CP_COMPARE_P_AND_T
694      .set OPERATION_TYPE,  T_OPERATION
695      select_destination destination
696     ;
697     ; 29027 registers are not valid destinations for compare operations
698     ; If the destination is a 29000 register, write the appropriate
699     ; Boolean value to that register.
700     ;
701      .if ( DESTINATION == DESTINATION_29027 )
702        .err
703        .print "29027 destinations invalid for compare - @destination@"
704        .exitm
705      .else
706        perform_double_operation destination, operand1, operand2
707        cp_read_flags destination
708        srl  destination,  destination, CP_EQUAL_FLAG_POSITION
709        sll  destination,  destination,  31
710      .endif
711    .else
712   ;
713   ; For 29000 mode (the default) just invoke the trap-inducing instruction
714   ;
715      deq destination,operand1,operand2
716 
717    .endif
718 
719  .endm        ; end of mdeq macro definition
720 
721 ;
722 ;  SMART MACRO: mdge
723 ;
724 ;  FUNCTION: Double precision, floating point compare
725 ;
726 ;  PARAMETERS:  destination  -  one of the possible destinations
727 ;               operand1     -  one of the possible sources
728 ;               operand2     -  one of the possible sources
729 ;
730  .macro mdge, destination, operand1, operand2
731 
732    .if $narg!=3
733      .err
734      .print "mdge: missing parameter(s)"
735      .exitm
736    .endif
737 
738 
739    .ifdef _29027_MODE
740   ;
741   ; Generate in line 29027 code
742   ;
743      initialize_previous_instruction
744      .set CURRENT_INSTRUCTION, CP_D_D  | CP_COMPARE_P_AND_T
745      .set OPERATION_TYPE,  T_OPERATION
746      select_destination destination
747     ;
748     ; 29027 registers are not valid destinations for compare operations
749     ; If the destination is a 29000 register, write the appropriate
750     ; Boolean value to that register.
751     ;
752      .if ( DESTINATION == DESTINATION_29027 )
753        .err
754        .print "29027 destinations invalid for compare - @destination@"
755        .exitm
756      .else
757        perform_double_operation destination, operand1, operand2
758        cp_read_flags destination
759        and   destination,  destination,  CP_EQUAL_FLAG | CP_GREATER_THAN_FLAG
760        cpneq destination,  destination,  0x0
761      .endif
762    .else
763   ;
764   ; For 29000 mode (the default) just invoke the trap-inducing instruction
765   ;
766      dge destination,operand1,operand2
767 
768    .endif
769 
770  .endm        ; end of mdge macro definition
771 
772 ;
773 ;  SMART MACRO: mdgt
774 ;
775 ;  FUNCTION: Double precision, floating point compare
776 ;
777 ;  PARAMETERS:  destination  -  one of the possible destinations
778 ;               operand1     -  one of the possible sources
779 ;               operand2     -  one of the possible sources
780 ;
781  .macro mdgt, destination, operand1, operand2
782 
783    .if $narg!=3
784      .err
785      .print "mdgt: missing parameter(s)"
786      .exitm
787    .endif
788 
789 
790    .ifdef _29027_MODE
791   ;
792   ; Generate in line 29027 code
793   ;
794      initialize_previous_instruction
795      .set CURRENT_INSTRUCTION, CP_D_D  | CP_COMPARE_P_AND_T
796      .set OPERATION_TYPE,  T_OPERATION
797      select_destination destination
798     ;
799     ; 29027 registers are not valid destinations for compare operations
800     ; If the destination is a 29000 register, write the appropriate
801     ; Boolean value to that register.
802     ;
803      .if ( DESTINATION == DESTINATION_29027 )
804        .err
805        .print "29027 destinations invalid for compare - @destination@"
806        .exitm
807      .else
808        perform_double_operation destination, operand1, operand2
809        cp_read_flags destination
810        srl  destination,  destination,  CP_GREATER_THAN_FLAG_POSITION
811        sll  destination,  destination,  31
812      .endif
813    .else
814   ;
815   ; For 29000 mode (the default) just invoke the trap-inducing instruction
816   ;
817      dgt destination,operand1,operand2
818 
819    .endif
820 
821  .endm    ; end of mdgt macro definition
822 
823 ;
824 ; MACRO NAME : perform_double_operation
825 ;
826 ; FUNCTION : After the instruction base is set up, do the appropriate checking
827 ;            to send the instruction if necessary, send the double-precision
828 ;            operands if necessary, and start the operation
829 ;
830 ; PARAMETERS : destination - one of possible destination operands
831 ;              operand1    - one of possible source operands
832 ;              operand2    - one of possible source operands
833 ;
834  .macro perform_double_operation,destination,operand1,operand2
835 
836    .if $narg!=3
837      .err
838      .print "perform_double_operation: missing parameter(s)"
839      .exitm
840    .endif
841 
842   ;
843   ; Start defining the instruction
844   ;
845    select_destination destination
846    select_P_operand   operand1
847    select_S_operand   operand2
848 
849    write_and_execute_double_operation operand1, operand2
850 
851  .endm      ; End of perform_double_operation macro definition
852 
853 ;
854 ; MACRO NAME : perform_single_operation
855 ;
856 ; FUNCTION : After the instruction base is set up, do the appropriate checking
857 ;            to send the instruction if necessary, send the single-precision
858 ;            operands if necessary and start the operation
859 ;
860 ; PARAMETERS : destination - one of possible destination operands
861 ;              operand1    - one of possible source operands
862 ;              operand2    - one of possible source operands
863 ;
864  .macro perform_single_operation,destination,operand1,operand2
865 
866   ;
867   ; Start defining the instruction
868   ;
869    select_destination destination
870    select_P_operand operand1
871    select_S_operand operand2
872    write_and_execute_single_operation operand1,operand2
873 
874  .endm      ; End of perform_single_operation macro definition
875 
876 ;
877 ; MACRO NAME : write_and_execute_double_operation
878 ;
879 ; FUNCTION : Write the instruction and operands for a double-precision
880 ;            operation, and start the operation
881 ;
882 ; PARAMETER : operand1 - first operand of double-precision operation
883 ;             operand2 - second operand of operation
884 ;
885  .macro write_and_execute_double_operation,operand1,operand2
886    .if ( ( R_SOURCE == R_SOURCE_29027 ) && ( S_SOURCE == S_SOURCE_29027 ) )
887   ;
888   ; If both sources are within the 29027, write the instruction
889   ; and start the operation
890   ;
891        const  t4, CURRENT_INSTRUCTION
892        consth t4, CURRENT_INSTRUCTION
893        cp_write_inst t4, START
894    .else
895   ;
896   ; One or both of the sources must be written first, so check the
897   ; previous instruction
898   ;
899        const  t4, CURRENT_INSTRUCTION
900        consth t4, CURRENT_INSTRUCTION
901        cp_write_inst t4
902      .if ( R_SOURCE == R_SOURCE_29000 ) && ( S_SOURCE == S_SOURCE_29027 )
903        .ifeqs "@operand1@","t0"
904          cp_write_r t0, t1, START
905        .else
906          .ifeqs "@operand1@","t2"
907            cp_write_r t2, t3, START
908          .else
909            .ifeqs "@operand1@","rtn0"
910              cp_write_r rtn0, rtn1, START
911            .else
912              .err
913              .print "Invalid source for double operation - @operand1@"
914              .exitm
915            .endif
916          .endif
917        .endif
918      .endif
919      .if ( R_SOURCE == R_SOURCE_29027 ) && ( S_SOURCE == S_SOURCE_29000 )
920        .ifeqs "@operand2@","t0"
921          cp_write_s t0, t1, START
922        .else
923          .ifeqs "@operand2@","t2"
924            cp_write_s t2, t3, START
925          .else
926            .ifeqs "@operand2@","rtn0"
927              cp_write_s rtn0, rtn1, START
928            .else
929              .err
930              .print "Invalid source for double operation - @operand1@"
931              .exitm
932            .endif
933          .endif
934        .endif
935      .endif
936      .if ( R_SOURCE == R_SOURCE_29000 ) && ( S_SOURCE == S_SOURCE_29000 )
937        .ifeqs "@operand1@","t0"
938          cp_write_r t0, t1
939        .else
940          .ifeqs "@operand1@","t2"
941            cp_write_r t2, t3
942          .else
943            .ifeqs "@operand1@","rtn0"
944              cp_write_r rtn0, rtn1
945            .else
946              .err
947              .print "Invalid source for double operation - @operand1@"
948              .exitm
949            .endif
950          .endif
951        .endif
952        .ifeqs "@operand2@","t0"
953          cp_write_s t0, t1, START
954        .else
955          .ifeqs "@operand2@","t2"
956            cp_write_s t2, t3, START
957          .else
958            .ifeqs "@operand2@","rtn0"
959              cp_write_s rtn0, rtn1, START
960            .else
961              .err
962              .print "Invalid source for double operation - @operand1@"
963              .exitm
964            .endif
965          .endif
966        .endif
967      .endif
968    .endif
969 
970  .endm       ; end of write_and_execute_double_operation macro definition
971 
972 ;
973 ; MACRO NAME : write_and_execute_single_operation
974 ;
975 ; FUNCTION : If necessary, read the result from the 29027 into a
976 ;            register on the 29000
977 ;
978 ; PARAMETER : operand1 - first source for single-precision operation
979 ;             operand2 - second source for operation
980 ;
981  .macro write_and_execute_single_operation,operand1,operand2
982 
983    .if ( ( R_SOURCE == R_SOURCE_29027 ) && ( S_SOURCE == S_SOURCE_29027 ) )
984   ;
985   ; If both sources are within the 29027, write the instruction
986   ; and start the operation
987   ;
988        const  t4, CURRENT_INSTRUCTION
989        consth t4, CURRENT_INSTRUCTION
990        cp_write_inst t4, START
991    .else
992   ;
993   ; One or both of the sources must be written first, so check the
994   ; previous instruction
995   ;
996      const  t4,CURRENT_INSTRUCTION
997      consth t4,CURRENT_INSTRUCTION
998      cp_write_inst t4, START
999      .if ( R_SOURCE == R_SOURCE_29000 ) && ( S_SOURCE == S_SOURCE_29027 )
1000        cp_write_r operand1, operand1, START
1001      .endif
1002      .if ( R_SOURCE == R_SOURCE_29027 ) && ( S_SOURCE == S_SOURCE_29000 )
1003        cp_write_s operand2, operand2, START
1004      .endif
1005      .if ( R_SOURCE == R_SOURCE_29000 ) && ( S_SOURCE == S_SOURCE_29000 )
1006        cp_write_rs operand1, operand2, START
1007      .endif
1008    .endif
1009 
1010  .endm      ; End of write_and_execute_single_operation macro definition
1011 
1012 ;
1013 ; MACRO NAME : read_double_result
1014 ;
1015 ; FUNCTION : If necessary, read the result from the 29027 into a
1016 ;            register on the 29000
1017 ;
1018 ; PARAMETER : destination - one of the possible destination registers
1019 ;
1020  .macro read_double_result,destination
1021    .if ( DESTINATION == DESTINATION_29000 )
1022   ;
1023   ; If the destination is not within the 29027 register file, read
1024   ; the result and store it into the correct register in the 29000
1025   ;
1026      .ifeqs "@destination@","rtn0"
1027        cp_read_dp rtn0, rtn1
1028      .else
1029        .err
1030        .print "Invalid destination for double result - @destination@"
1031        .exitm
1032      .endif
1033    .endif
1034 
1035  .endm       ; End of read_double_result macro definition
1036 
1037 ;
1038 ; MACRO NAME : read_single_result
1039 ;
1040 ; FUNCTION : If necessary, read the result from the 29027 into a
1041 ;            register on the 29000
1042 ;
1043 ; PARAMETER : destination
1044 ;
1045  .macro read_single_result,destination
1046 
1047    .if ( DESTINATION == DESTINATION_29000 )
1048   ;
1049   ; If the destination is not within the 29027 register file, read
1050   ; the result and store it into the correct register in the 29000
1051   ;
1052      .ifeqs "@destination@","rtn0"
1053        cp_read_sp rtn0
1054      .else
1055        .err
1056        .print "Invalid destination for single result - @destination@"
1057        .exitm
1058      .endif
1059    .endif
1060 
1061  .endm       ; End of read_single_result macro definition
1062 
1063 ;
1064 ; MACRO NAME : read_integer_result
1065 ;
1066 ; FUNCTION : If necessary, read the result from the 29027 into a
1067 ;            register on the 29000
1068 ;
1069 ; PARAMETER : destination
1070 ;
1071  .macro read_integer_result,destination
1072 
1073    .if ( DESTINATION == DESTINATION_29000 )
1074   ;
1075   ; If the destination is not within the 29027 register file, read
1076   ; the result and store it into the correct register in the 29000
1077   ;
1078      .ifeqs "@destination@","rtn0"
1079        cp_read_int rtn0
1080      .else
1081        .err
1082        .print "Invalid destination for single result - @destination@"
1083        .exitm
1084      .endif
1085    .endif
1086 
1087  .endm       ; End of read_integer_result macro definition
1088 
1089 ;
1090 ; MACRO NAME : select_P_operand
1091 ;
1092 ; FUNCTION : Given an operand, determine if the operand is from the
1093 ;            register file, and if so, set the appropriate bits in
1094 ;            the current instruction word.  In addition, set the
1095 ;            variable R_SOURCE to 0 for local register file, or 1 for
1096 ;            floating-point register file.
1097 ;
1098 ; PARAMETER : operand1 - one of the possible source operands
1099 ;
1100  .macro select_P_operand,operand1
1101    .ifeqs "@operand1@","t0"
1102      .set R_SOURCE,R_SOURCE_29000
1103      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_R
1104      .exitm
1105    .endif
1106    .ifeqs "@operand1@","t2"
1107      .set R_SOURCE,R_SOURCE_29000
1108      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_R
1109      .exitm
1110    .endif
1111    .ifeqs "@operand1@","rtn0"
1112      .set R_SOURCE,R_SOURCE_29000
1113      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_R
1114      .exitm
1115    .endif
1116    .ifeqs "@operand1@","FP0"
1117      .set R_SOURCE,R_SOURCE_29027
1118      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_RF0
1119      .exitm
1120    .endif
1121    .ifeqs "@operand1@","FP1"
1122      .set R_SOURCE,R_SOURCE_29027
1123      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_RF1
1124      .exitm
1125    .endif
1126    .ifeqs "@operand1@","FP2"
1127      .set R_SOURCE,R_SOURCE_29027
1128      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_RF2
1129      .exitm
1130    .endif
1131    .ifeqs "@operand1@","FP3"
1132      .set R_SOURCE,R_SOURCE_29027
1133      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_RF3
1134      .exitm
1135    .endif
1136    .ifeqs "@operand1@","FP4"
1137      .set R_SOURCE,R_SOURCE_29027
1138      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_RF4
1139      .exitm
1140    .endif
1141    .ifeqs "@operand1@","FP5"
1142      .set R_SOURCE,R_SOURCE_29027
1143      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_RF5
1144      .exitm
1145    .endif
1146    .ifeqs "@operand1@","FP6"
1147      .set R_SOURCE,R_SOURCE_29027
1148      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_RF6
1149      .exitm
1150    .endif
1151    .ifeqs "@operand1@","FP7"
1152      .set R_SOURCE,R_SOURCE_29027
1153      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_RF7
1154      .exitm
1155    .endif
1156    .err
1157    .print "@operand1@ - Invalid operand"
1158 
1159  .endm        ; end of select_P_operand macro definition
1160 
1161 ;
1162 ; MACRO NAME : select_S_operand
1163 ;
1164 ; FUNCTION : Given an operand, determine if the operand is from the
1165 ;            register file, and if so, set the appropriate bits in
1166 ;            the current instruction word.  In addition, set the
1167 ;            variable S_SOURCE to S_SOURCE_29000 or S_SOURCE_29027
1168 ;            as appropriate
1169 ;
1170 ; PARAMETER : operand2 - one of the possible source operands
1171 ;
1172  .macro select_S_operand,operand2
1173    .ifeqs "@operand2@","t0"
1174      .set S_SOURCE,S_SOURCE_29000
1175      .if ( OPERATION_TYPE == T_OPERATION )
1176        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_S
1177      .else
1178        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_S
1179      .endif
1180      .exitm
1181    .endif
1182    .ifeqs "@operand2@","t2"
1183      .set S_SOURCE,S_SOURCE_29000
1184      .if ( OPERATION_TYPE == T_OPERATION )
1185        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_S
1186      .else
1187        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_S
1188      .endif
1189      .exitm
1190    .endif
1191    .ifeqs "@operand2@","rtn0"
1192      .set S_SOURCE,S_SOURCE_29000
1193      .if ( OPERATION_TYPE == T_OPERATION )
1194        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_S
1195      .else
1196        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_S
1197      .endif
1198      .exitm
1199    .endif
1200    .ifeqs "@operand2@","FP0"
1201      .set S_SOURCE,S_SOURCE_29027
1202      .if ( OPERATION_TYPE == T_OPERATION )
1203        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF0
1204      .else
1205        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_RF0
1206      .endif
1207      .exitm
1208    .endif
1209    .ifeqs "@operand2@","FP1"
1210      .set S_SOURCE,S_SOURCE_29027
1211      .if ( OPERATION_TYPE == T_OPERATION )
1212        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF1
1213      .else
1214        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_RF1
1215      .endif
1216      .exitm
1217    .endif
1218    .ifeqs "@operand2@","FP2"
1219      .set S_SOURCE,S_SOURCE_29027
1220      .if ( OPERATION_TYPE == T_OPERATION )
1221        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF2
1222      .else
1223        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_RF2
1224      .endif
1225      .exitm
1226    .endif
1227    .ifeqs "@operand2@","FP3"
1228      .set S_SOURCE,S_SOURCE_29027
1229      .if ( OPERATION_TYPE == T_OPERATION )
1230        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF3
1231      .else
1232        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_RF3
1233      .endif
1234      .exitm
1235    .endif
1236    .ifeqs "@operand2@","FP4"
1237      .set S_SOURCE,S_SOURCE_29027
1238      .if ( OPERATION_TYPE == T_OPERATION )
1239        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF4
1240      .else
1241        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_RF4
1242      .endif
1243      .exitm
1244    .endif
1245    .ifeqs "@operand2@","FP5"
1246      .set S_SOURCE,S_SOURCE_29027
1247      .if ( OPERATION_TYPE == T_OPERATION )
1248        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF5
1249      .else
1250        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_RF5
1251      .endif
1252      .exitm
1253    .endif
1254    .ifeqs "@operand2@","FP6"
1255      .set S_SOURCE,S_SOURCE_29027
1256      .if ( OPERATION_TYPE == T_OPERATION )
1257        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF6
1258      .else
1259        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_RF6
1260      .endif
1261      .exitm
1262    .endif
1263    .ifeqs "@operand2@","FP7"
1264      .set S_SOURCE,S_SOURCE_29027
1265      .if ( OPERATION_TYPE == T_OPERATION )
1266        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF7
1267      .else
1268        .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_RF7
1269      .endif
1270      .exitm
1271    .endif
1272    .err
1273    .print "@operand2@ - Invalid operand"
1274 
1275  .endm        ; end of select_S_operand macro definition
1276 
1277 ;
1278 ; MACRO NAME : select_T_operand
1279 ;
1280 ; FUNCTION : Given an operand, determine if the operand is from the
1281 ;            register file, and if so, set the appropriate bits in
1282 ;            the current instruction word, to read the corresponding
1283 ;            source into the T operand.  In addition, set the
1284 ;            variable R_SOURCE to 0 for local register file, or 1 for
1285 ;            floating-point register file.
1286 ;
1287 ; PARAMETER : operand1 - one of the possible source operands
1288 ;
1289  .macro select_T_operand,operand1
1290    .ifeqs "@operand1@","t0"
1291      .set R_SOURCE,R_SOURCE_29000
1292      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_R
1293      .exitm
1294    .endif
1295    .ifeqs "@operand1@","t2"
1296      .set R_SOURCE,R_SOURCE_29000
1297      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_R
1298      .exitm
1299    .endif
1300    .ifeqs "@operand1@","rtn0"
1301      .set R_SOURCE,R_SOURCE_29000
1302      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_R
1303      .exitm
1304    .endif
1305    .ifeqs "@operand1@","FP0"
1306      .set R_SOURCE,R_SOURCE_29027
1307      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF0
1308      .exitm
1309    .endif
1310    .ifeqs "@operand1@","FP1"
1311      .set R_SOURCE,R_SOURCE_29027
1312      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF1
1313      .exitm
1314    .endif
1315    .ifeqs "@operand1@","FP2"
1316      .set R_SOURCE,R_SOURCE_29027
1317      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF2
1318      .exitm
1319    .endif
1320    .ifeqs "@operand1@","FP3"
1321      .set R_SOURCE,R_SOURCE_29027
1322      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF3
1323      .exitm
1324    .endif
1325    .ifeqs "@operand1@","FP4"
1326      .set R_SOURCE,R_SOURCE_29027
1327      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF4
1328      .exitm
1329    .endif
1330    .ifeqs "@operand1@","FP5"
1331      .set R_SOURCE,R_SOURCE_29027
1332      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF5
1333      .exitm
1334    .endif
1335    .ifeqs "@operand1@","FP6"
1336      .set R_SOURCE,R_SOURCE_29027
1337      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF6
1338      .exitm
1339    .endif
1340    .ifeqs "@operand1@","FP7"
1341      .set R_SOURCE,R_SOURCE_29027
1342      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF7
1343      .exitm
1344    .endif
1345    .err
1346    .print "@operand1@ - Invalid operand"
1347 
1348  .endm        ; end of select_T_operand macro definition
1349 
1350 ;
1351 ; MACRO NAME : select_destination
1352 ;
1353 ; FUNCTION : Given a destination, determine if the operand is from the
1354 ;            register file, and if so, set the appropriate bits in
1355 ;            the current instruction word.  In addition, set the
1356 ;            variable DESTINATION to DESTINATION_29000 or
1357 ;            DESTINATION_29027 as appropriate
1358 ;
1359 ; PARAMETER : destination - one of the possible destination operands
1360 ;
1361  .macro select_destination,destination
1362    .ifeqs "@destination@","rtn0"
1363      .set DESTINATION,DESTINATION_29000
1364      .exitm
1365    .endif
1366    .ifeqs "@destination@","FP0"
1367      .set DESTINATION,DESTINATION_29027
1368      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_DEST_EQ_RF0
1369      .exitm
1370    .endif
1371    .ifeqs "@destination@","FP1"
1372      .set DESTINATION,DESTINATION_29027
1373      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_DEST_EQ_RF1
1374      .exitm
1375    .endif
1376    .ifeqs "@destination@","FP2"
1377      .set DESTINATION,DESTINATION_29027
1378      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_DEST_EQ_RF2
1379      .exitm
1380    .endif
1381    .ifeqs "@destination@","FP3"
1382      .set DESTINATION,DESTINATION_29027
1383      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_DEST_EQ_RF3
1384      .exitm
1385    .endif
1386    .ifeqs "@destination@","FP4"
1387      .set DESTINATION,DESTINATION_29027
1388      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_DEST_EQ_RF4
1389      .exitm
1390    .endif
1391    .ifeqs "@destination@","FP5"
1392      .set DESTINATION,DESTINATION_29027
1393      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_DEST_EQ_RF5
1394      .exitm
1395    .endif
1396    .ifeqs "@destination@","FP6"
1397      .set DESTINATION,DESTINATION_29027
1398      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_DEST_EQ_RF6
1399      .exitm
1400    .endif
1401    .ifeqs "@destination@","FP7"
1402      .set DESTINATION,DESTINATION_29027
1403      .set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_DEST_EQ_RF7
1404      .exitm
1405    .endif
1406    .err
1407    .print "@destination@ - Invalid operand"
1408 
1409  .endm        ; end of select_destination macro definition
1410 
1411 ; MACRO NAME : initialize_previous_instruction
1412 ;
1413 ; FUNCTION : Make sure the previous instruction is defined and set to zero
1414 ;
1415  .macro initialize_previous_instruction
1416 
1417    .ifndef PREVIOUS_INSTRUCTION
1418   ;
1419   ; Make sure that the previous instruction variable is initialized
1420   ;
1421      .set PREVIOUS_INSTRUCTION,0
1422    .endif
1423 
1424  .endm        ; end of initialize_previous_instruction macro definition
1425 
1426 
1427 ; MACRO NAME : prepare_function_parameters
1428 ;
1429 ; FUNCTION : To place the input parameters into the correct position for
1430 ;            use by the function body.  When the target language is
1431 ;            FORTRAN, the values of the input arguments are read from the
1432 ;            supplied addresses and moved to the t0-t3 temporary area.
1433 ;            When the target language is C or Pascal, the values of the
1434 ;            input arguments are simply moved to the t0-t3 temporary area.
1435 ;
1436  .macro prepare_function_parameters,arg1,arg2
1437 
1438    .if $narg==0
1439      .err
1440      .print "Missing function argument(s)"
1441      .exitm
1442    .endif
1443 
1444    .if $narg>2
1445      .err
1446      .print "Too many function arguments
1447      .exitm
1448    .endif
1449 
1450    .if $narg>=1
1451      .if $isreg(@arg1)
1452        .ifdef FORTRAN
1453          load 0,0,t0,arg1
1454          .if ( FUNCTION_TYPE == DOUBLE_FUNCTION )
1455            add t1,arg1,4
1456            load 0,0,t1,t1
1457          .endif
1458        .else
1459          add t0,arg1,0
1460          .if ( FUNCTION_TYPE == DOUBLE_FUNCTION )
1461            add t1,%%(&arg1+1),0
1462          .endif
1463        .endif
1464      .else
1465        .err
1466        .print "Function argument not register - @arg1@"
1467      .endif
1468    .endif
1469    .if $narg==2
1470      .if $isreg (@arg2)
1471        .ifdef FORTRAN
1472          load 0,0,t2,arg2
1473          .if ( FUNCTION_TYPE == DOUBLE_FUNCTION )
1474            add t3,arg2,4
1475            load 0,0,t3,t3
1476          .endif
1477        .else
1478          add t2,arg2,0
1479          .if ( FUNCTION_TYPE == DOUBLE_FUNCTION )
1480            add t3,%%(&arg2+1),0
1481          .endif
1482        .endif
1483      .else
1484        .err
1485        .print "Function argument not register - @arg2@"
1486      .endif
1487    .endif
1488 
1489  .endm ; end of prepare_function_parameters macro definition
1490 
1491 ; end of smartmac.h file
1492