1492 lines
42 KiB
C
1492 lines
42 KiB
C
; @(#)smartmac.h 1.2 90/10/14 20:56:14, AMD
|
|
; start of smartmac.h file
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; Copyright 1988, 1989, 1990 Advanced Micro Devices, Inc.
|
|
;
|
|
; This software is the property of Advanced Micro Devices, Inc (AMD) which
|
|
; specifically grants the user the right to modify, use and distribute this
|
|
; software provided this notice is not removed or altered. All other rights
|
|
; are reserved by AMD.
|
|
;
|
|
; AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS
|
|
; SOFTWARE. IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL
|
|
; DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR
|
|
; USE OF THIS SOFTWARE.
|
|
;
|
|
; So that all may benefit from your experience, please report any problems
|
|
; or suggestions about this software to the 29K Technical Support Center at
|
|
; 800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131 in the UK, or
|
|
; 0031-11-1129 in Japan, toll free. The direct dial number is 512-462-4118.
|
|
;
|
|
; Advanced Micro Devices, Inc.
|
|
; 29K Support Products
|
|
; Mail Stop 573
|
|
; 5900 E. Ben White Blvd.
|
|
; Austin, TX 78741
|
|
; 800-292-9263
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;
|
|
;
|
|
.title "AM29000 Smart Macro Package"
|
|
;
|
|
; Floating point package for AMD 29000 family
|
|
;
|
|
; Copyright 1988 Advanced Micro Devices, Inc.
|
|
;
|
|
; All rights reserved
|
|
;
|
|
; Developed for AMD by Quantitative Technology Corporation
|
|
; 8700 SW Creekside Place Suite D
|
|
; Beaverton OR 97005
|
|
; (503) 626-3081
|
|
;
|
|
; Version information :
|
|
;
|
|
; Version 1.0 - 1 June 1988 - Larry Westerman (smart_macros.h)
|
|
;
|
|
; Revision 1.4 89/02/01 18:26:03 jimh
|
|
; Changed to relect the new symbols from Bob Perlman, and the new include file.s
|
|
;
|
|
; Revision 1.3 89/01/31 10:13:34 jimh
|
|
; Updated to use symbols from Bob Perlmans fpsymbol.h file. This is
|
|
; an extensive change.
|
|
;
|
|
; Revision 1.2 89/01/26 09:23:50 jimh
|
|
; This version checked in previous to substituting Bob Perlman's floating
|
|
; point symbols.
|
|
;
|
|
; Revision 1.1 89/01/24 13:23:29 jim
|
|
; Initial revision
|
|
; Replaces smart_macros.h ver 1.11.
|
|
;
|
|
;
|
|
;
|
|
;
|
|
; NOTES:
|
|
;
|
|
; This package makes the following assumptions about the use of these
|
|
; smart macros:
|
|
;
|
|
; 1. These macros will be after the entry code for a transcendental
|
|
; routine. This entry code will move the original function arguments
|
|
; (by value, if the target language is FORTRAN) into the global
|
|
; registers t0/t1 and t2/t3 (t0 and t2 for single precision
|
|
; routines).
|
|
; 2. The sources of all operands will be one register from the
|
|
; following list:
|
|
; t0 or t2 - the source is one of the original input operands
|
|
; rtn0 - the source is rtn0, which should be used as the
|
|
; source for all constant values to be sent to the
|
|
; AM29027 (when used)
|
|
; FP0 - FP7 - the source is one of the fp registers
|
|
; 3. The destination of all operations will be a register from the
|
|
; following list:
|
|
; rtn0 - the destination is the function return value
|
|
; FP0 - FP7 - the destination is one of the fp registers
|
|
; 4. The additional registers available for temporary use are
|
|
; t4, lrp, and slp.
|
|
;
|
|
; These register definitions are all taken from the file "proregs.a"
|
|
; which was supplied by AMD. NOTE that the FP0-FP7 registers, for the
|
|
; Am29000 version of the file, overlap with the rtn0-rtn15 registers, so
|
|
; that FP0 corresponds to rtn0/rtn1, FP1 to rtn2/rtn3, and so forth.
|
|
;
|
|
.equ ERROR,0
|
|
.equ NO_ERROR,1
|
|
|
|
.equ DOUBLE_FUNCTION,0
|
|
.equ SINGLE_FUNCTION,1
|
|
|
|
.equ T_OPERATION,0
|
|
.equ Q_OPERATION,1
|
|
|
|
.equ R_SOURCE_29000,0
|
|
.equ R_SOURCE_29027,1
|
|
|
|
.equ S_SOURCE_29000,0
|
|
.equ S_SOURCE_29027,1
|
|
|
|
.equ DESTINATION_29000, 0
|
|
.equ DESTINATION_29027, 1
|
|
|
|
;
|
|
; SMART MACRO : mfadd
|
|
;
|
|
; FUNCTION : single-precision floating point addition
|
|
;
|
|
; Required arguments : destination - one of possible destinations
|
|
; operand1 - one of possible sources
|
|
; operand2 - one of possible sources
|
|
;
|
|
.macro mfadd,destination,operand1,operand2
|
|
|
|
.if $narg!=3
|
|
.err
|
|
.print "mfadd: missing parameter(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
.ifdef _29027_MODE
|
|
;
|
|
; For 29027 mode, perform full suite of checking
|
|
;
|
|
initialize_previous_instruction
|
|
.set CURRENT_INSTRUCTION, CP_S_S | CP_P_PLUS_T
|
|
.set OPERATION_TYPE, T_OPERATION
|
|
perform_single_operation destination,operand1,operand2
|
|
read_single_result destination
|
|
;
|
|
; Save the instruction for the next macro invocation
|
|
;
|
|
.set PREVIOUS_INSTRUCTION, CURRENT_INSTRUCTION
|
|
|
|
.else
|
|
;
|
|
; For 29000 mode, simply produce equivalent trap-inducing instruction
|
|
;
|
|
fadd destination,operand1,operand2
|
|
|
|
.endif
|
|
|
|
.endm ; end of mfadd macro definition
|
|
|
|
;
|
|
; SMART MACRO : mfsub
|
|
;
|
|
; FUNCTION : single-precision floating point subtraction
|
|
;
|
|
; Required arguments : destination - one of possible destinations
|
|
; operand1 - one of possible sources
|
|
; operand2 - one of possible sources
|
|
;
|
|
.macro mfsub,destination,operand1,operand2
|
|
|
|
.if $narg!=3
|
|
.err
|
|
.print "mfsub: missing parameter(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
.ifdef _29027_MODE
|
|
;
|
|
; For 29027 mode, perform full suite of checking
|
|
;
|
|
initialize_previous_instruction
|
|
.set CURRENT_INSTRUCTION, CP_S_S | CP_P_MINUS_T
|
|
.set OPERATION_TYPE, T_OPERATION
|
|
perform_single_operation destination,operand1,operand2
|
|
read_single_result destination
|
|
;
|
|
; Save the instruction for the next macro invocation
|
|
;
|
|
.set PREVIOUS_INSTRUCTION, CURRENT_INSTRUCTION
|
|
|
|
.else
|
|
;
|
|
; For 29000 mode, simply produce equivalent trap-inducing instruction
|
|
;
|
|
fsub destination,operand1,operand2
|
|
|
|
.endif
|
|
|
|
.endm ; end of mfsub macro definition
|
|
|
|
;
|
|
; SMART MACRO : mfmul
|
|
;
|
|
; FUNCTION : single-precision floating point multiplication
|
|
;
|
|
; Required arguments : destination - one of possible destinations
|
|
; operand1 - one of possible sources
|
|
; operand2 - one of possible sources
|
|
;
|
|
.macro mfmul,destination,operand1,operand2
|
|
|
|
.if $narg!=3
|
|
.err
|
|
.print "mfmul: missing parameter(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
.ifdef _29027_MODE
|
|
;
|
|
; For 29027 mode, perform full suite of checking
|
|
;
|
|
initialize_previous_instruction
|
|
.set CURRENT_INSTRUCTION, CP_S_S | CP_P_TIMES_Q
|
|
.set OPERATION_TYPE, Q_OPERATION
|
|
perform_single_operation destination,operand1,operand2
|
|
read_single_result destination
|
|
;
|
|
; Save the instruction for the next macro invocation
|
|
;
|
|
.set PREVIOUS_INSTRUCTION, CURRENT_INSTRUCTION
|
|
|
|
.else
|
|
;
|
|
; For 29000 mode, simply produce equivalent trap-inducing instruction
|
|
;
|
|
fmul destination,operand1,operand2
|
|
|
|
.endif
|
|
|
|
.endm ; end of mfmul macro definition
|
|
|
|
;
|
|
; SMART MACRO : mfdiv
|
|
;
|
|
; FUNCTION : single-precision floating point divide
|
|
;
|
|
; Required arguments : destination - one of possible destinations
|
|
; operand1 - one of possible sources
|
|
; operand2 - one of possible sources
|
|
;
|
|
.macro mfdiv,destination,operand1,operand2
|
|
|
|
.if $narg!=3
|
|
.err
|
|
.print "mfdiv: missing parameter(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
;
|
|
; Generate the trap instruction in all cases
|
|
;
|
|
fdiv destination, operand1, operand2
|
|
|
|
.endm ; end of mfdiv macro definition
|
|
|
|
|
|
;
|
|
; SMART MACRO : mdadd
|
|
;
|
|
; FUNCTION : double-precision floating point addition
|
|
;
|
|
; Required arguments : destination - one of possible destinations
|
|
; operand1 - one of possible sources
|
|
; operand2 - one of possible sources
|
|
;
|
|
.macro mdadd,destination,operand1,operand2
|
|
|
|
.if $narg!=3
|
|
.err
|
|
.print "mdadd: missing parameter(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
.ifdef _29027_MODE
|
|
;
|
|
; For 29027 mode, perform full suite of checking
|
|
;
|
|
initialize_previous_instruction
|
|
.set CURRENT_INSTRUCTION, CP_D_D | CP_P_PLUS_T
|
|
.set OPERATION_TYPE, T_OPERATION
|
|
perform_double_operation destination,operand1,operand2
|
|
read_double_result destination
|
|
;
|
|
; Save the instruction for the next macro invocation
|
|
;
|
|
.set PREVIOUS_INSTRUCTION, CURRENT_INSTRUCTION
|
|
|
|
.else
|
|
;
|
|
; For 29000 mode, simply produce equivalent trap-inducing instruction
|
|
;
|
|
dadd destination,operand1,operand2
|
|
|
|
.endif
|
|
|
|
.endm ; end of mdadd macro definition
|
|
|
|
;
|
|
; SMART MACRO : mdsub
|
|
;
|
|
; FUNCTION : double-precision floating point subtraction
|
|
;
|
|
; Required arguments : destination - one of possible destinations
|
|
; operand1 - one of possible sources
|
|
; operand2 - one of possible sources
|
|
;
|
|
.macro mdsub,destination,operand1,operand2
|
|
|
|
.if $narg!=3
|
|
.err
|
|
.print "mdsub: missing parameter(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
.ifdef _29027_MODE
|
|
;
|
|
; For 29027 mode, perform full suite of checking
|
|
;
|
|
initialize_previous_instruction
|
|
.set CURRENT_INSTRUCTION, CP_D_D | CP_P_MINUS_T
|
|
.set OPERATION_TYPE, T_OPERATION
|
|
perform_double_operation destination,operand1,operand2
|
|
read_double_result destination
|
|
;
|
|
; Save the instruction for the next macro invocation
|
|
;
|
|
.set PREVIOUS_INSTRUCTION, CURRENT_INSTRUCTION
|
|
|
|
.else
|
|
;
|
|
; For 29000 mode, simply produce equivalent trap-inducing instruction
|
|
;
|
|
dsub destination,operand1,operand2
|
|
|
|
.endif
|
|
|
|
.endm ; end of mdsub macro definition
|
|
|
|
;
|
|
; SMART MACRO : mdmul
|
|
;
|
|
; FUNCTION : double-precision floating point multiplication
|
|
;
|
|
; Required arguments : destination - one of possible destinations
|
|
; operand1 - one of possible sources
|
|
; operand2 - one of possible sources
|
|
;
|
|
.macro mdmul,destination,operand1,operand2
|
|
|
|
.if $narg!=3
|
|
.err
|
|
.print "mdmul: missing parameter(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
.ifdef _29027_MODE
|
|
;
|
|
; For 29027 mode, perform full suite of checking
|
|
;
|
|
initialize_previous_instruction
|
|
.set CURRENT_INSTRUCTION, CP_D_D | CP_P_TIMES_Q
|
|
.set OPERATION_TYPE, Q_OPERATION
|
|
perform_double_operation destination,operand1,operand2
|
|
read_double_result destination
|
|
;
|
|
; Save the instruction for the next macro invocation
|
|
;
|
|
.set PREVIOUS_INSTRUCTION, CURRENT_INSTRUCTION
|
|
|
|
.else
|
|
;
|
|
; For 29000 mode, simply produce equivalent trap-inducing instruction
|
|
;
|
|
dmul destination,operand1,operand2
|
|
|
|
.endif
|
|
|
|
.endm ; end of mdmul macro definition
|
|
|
|
;
|
|
; SMART MACRO : mddiv
|
|
;
|
|
; FUNCTION : double-precision floating point divide
|
|
;
|
|
; Required arguments : destination - one of possible destinations
|
|
; operand1 - one of possible sources
|
|
; operand2 - one of possible sources
|
|
;
|
|
.macro mddiv,destination,operand1,operand2
|
|
|
|
.if $narg!=3
|
|
.err
|
|
.print "mddiv: missing parameter(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
;
|
|
; Generate the trap instruction in all cases
|
|
;
|
|
ddiv destination, operand1, operand2
|
|
|
|
.endm ; end of mfdiv macro definition
|
|
|
|
;
|
|
; SMART MACRO: mconvert
|
|
;
|
|
; FUNCTION: Floating point/integer conversion
|
|
;
|
|
; PARAMETERS: destination - one of the possible destinations
|
|
; source - one of the possible sources
|
|
; sign_flag - one of SIGNED or UNSIGNED
|
|
; rounding_mode - one of ROUND_TO_NEAREST, ROUND_TO_PLUS,
|
|
; ROUND_TO_MINUS, ROUND_TO_ZERO
|
|
; destination_precision - one of FORMAT_INTEGER, FORMAT_DOUBLE,
|
|
; or FORMAT_SINGLE
|
|
; source_precision - one of FORMAT_INTEGER, FORMAT_DOUBLE,
|
|
; or FORMAT_SINGLE
|
|
;
|
|
.macro mconvert, destination, source, sign_flag, rounding_mode, destination_precision, source_precision
|
|
|
|
.if $narg!=6
|
|
.err
|
|
.print "mconvert: missing parameter(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
.ifdef _29027_MODE
|
|
;
|
|
; Generate in line 29027 code
|
|
;
|
|
initialize_previous_instruction
|
|
.if ( destination_precision == FORMAT_INTEGER )
|
|
.set CURRENT_INSTRUCTION, CP_CONVERT_T_TO_INT
|
|
select_T_operand source
|
|
.if ( source_precision == FORMAT_DOUBLE )
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_S_D
|
|
.else
|
|
.if ( source_precision == FORMAT_SINGLE )
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_S_S
|
|
.else
|
|
.err
|
|
.print "mconvert: invalid source type"
|
|
.exitm
|
|
.endif
|
|
.endif
|
|
.else
|
|
.if ( destination_precision == FORMAT_DOUBLE )
|
|
.if ( source_precision == FORMAT_SINGLE )
|
|
.set CURRENT_INSTRUCTION, CP_PASS_P | CP_P_EQ_R | CP_D_S
|
|
select_P_operand source
|
|
.else
|
|
.if ( source_precision == FORMAT_INTEGER )
|
|
.set CURRENT_INSTRUCTION, CP_I_CONVERT_T_TO_FLOAT | CP_D_S
|
|
select_T_operand source
|
|
.else
|
|
.err
|
|
.print "mconvert: invalid source type"
|
|
.exitm
|
|
.endif
|
|
.endif
|
|
.else
|
|
.if ( destination_precision == FORMAT_SINGLE )
|
|
.if ( source_precision == FORMAT_DOUBLE )
|
|
.set CURRENT_INSTRUCTION, CP_PASS_P | CP_P_EQ_R | CP_S_D
|
|
select_P_operand source
|
|
.else
|
|
.if ( source_precision == FORMAT_INTEGER )
|
|
.set CURRENT_INSTRUCTION, CP_I_CONVERT_T_TO_FLOAT | CP_S_S
|
|
select_T_operand source
|
|
.else
|
|
.err
|
|
.print "mconvert: invalid source type"
|
|
.exitm
|
|
.endif
|
|
.endif
|
|
.else
|
|
.err
|
|
.print "mconvert: invalid destination type "
|
|
.exitm
|
|
.endif
|
|
.endif
|
|
.endif
|
|
;
|
|
; Perform the operation, using a 29027 dummy register as the second
|
|
; source operand, to avoid writing any data inappropriately to the
|
|
; 29027
|
|
;
|
|
select_destination destination
|
|
.set S_SOURCE, S_SOURCE_29027
|
|
.if ( source_precision == FORMAT_DOUBLE )
|
|
write_and_execute_double_operation source, FP0
|
|
.else
|
|
write_and_execute_single_operation source, FP0
|
|
.endif
|
|
.if ( destination_precision == FORMAT_DOUBLE )
|
|
read_double_result destination
|
|
.else
|
|
.if ( destination_precision == FORMAT_SINGLE )
|
|
read_single_result destination
|
|
.else
|
|
read_integer_result destination
|
|
.endif
|
|
.endif
|
|
.else
|
|
;
|
|
; For 29000 mode (the default) just invoke the trap-inducing instruction
|
|
;
|
|
convert destination,source,sign_flag,rounding_mode,destination_precision,source_precision
|
|
|
|
.endif
|
|
|
|
.endm ; end of mfeq macro definition
|
|
|
|
;
|
|
; SMART MACRO: mfeq
|
|
;
|
|
; FUNCTION: Single precision, floating point compare
|
|
;
|
|
; PARAMETERS: destination - one of the possible destinations
|
|
; operand1 - one of the possible sources
|
|
; operand2 - one of the possible sources
|
|
;
|
|
.macro mfeq, destination, operand1, operand2
|
|
|
|
.if $narg!=3
|
|
.err
|
|
.print "mfeq: missing parameter(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
.ifdef _29027_MODE
|
|
;
|
|
; Generate in line 29027 code
|
|
;
|
|
initialize_previous_instruction
|
|
.set CURRENT_INSTRUCTION, CP_S_S | CP_COMPARE_P_AND_T
|
|
.set OPERATION_TYPE, T_OPERATION
|
|
select_destination destination
|
|
;
|
|
; 29027 registers are not valid destinations for compare operations
|
|
; If the destination is a 29000 register, write the appropriate
|
|
; Boolean value to that register.
|
|
;
|
|
.if ( DESTINATION == DESTINATION_29027 )
|
|
.err
|
|
.print "29027 destinations invalid for compares - @destination@"
|
|
.exitm
|
|
.else
|
|
perform_single_operation destination, operand1, operand2
|
|
cp_read_flags destination
|
|
srl destination, destination, CP_EQUAL_FLAG_POSITION
|
|
sll destination, destination, 31
|
|
.endif
|
|
|
|
.else
|
|
;
|
|
; For 29000 mode (the default) just invoke the trap-inducing instruction
|
|
;
|
|
feq destination,operand1,operand2
|
|
|
|
.endif
|
|
|
|
.endm ; end of mfeq macro definition
|
|
|
|
;
|
|
; SMART MACRO: mfge
|
|
;
|
|
; FUNCTION: Single precision, floating point compare
|
|
;
|
|
; PARAMETERS: destination - one of the possible destinations
|
|
; operand1 - one of the possible sources
|
|
; operand2 - one of the possible sources
|
|
;
|
|
.macro mfge, destination, operand1, operand2
|
|
|
|
.if $narg!=3
|
|
.err
|
|
.print "mfge: missing parameter(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
.ifdef _29027_MODE
|
|
;
|
|
; Generate in line 29027 code
|
|
;
|
|
initialize_previous_instruction
|
|
.set CURRENT_INSTRUCTION, CP_S_S | CP_COMPARE_P_AND_T
|
|
.set OPERATION_TYPE, T_OPERATION
|
|
select_destination destination
|
|
;
|
|
; 29027 registers are not valid destinations for compare operations
|
|
; If the destination is a 29000 register, write the appropriate
|
|
; Boolean value to that register.
|
|
;
|
|
.if ( DESTINATION == DESTINATION_29027 )
|
|
.err
|
|
.print "29027 destinations invalid for compares - @destination@"
|
|
.exitm
|
|
.else
|
|
perform_single_operation destination, operand1, operand2
|
|
cp_read_flags destination
|
|
and destination, destination, CP_EQUAL_FLAG | CP_GREATER_THAN_FLAG
|
|
cpneq destination, destination, 0x0
|
|
.endif
|
|
|
|
.else
|
|
;
|
|
; For 29000 mode (the default) just invoke the trap-inducing instruction
|
|
;
|
|
fge destination,operand1,operand2
|
|
|
|
.endif
|
|
|
|
.endm ; end of mfge macro definition
|
|
|
|
;
|
|
; SMART MACRO: mfgt
|
|
;
|
|
; FUNCTION: Single precision, floating point compare
|
|
;
|
|
; PARAMETERS: destination - one of the possible destinations
|
|
; operand1 - one of the possible sources
|
|
; operand2 - one of the possible sources
|
|
;
|
|
.macro mfgt, destination, operand1, operand2
|
|
|
|
.if $narg!=3
|
|
.err
|
|
.print "mfgt: missing parameter(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
.ifdef _29027_MODE
|
|
;
|
|
; Generate in line 29027 code
|
|
;
|
|
initialize_previous_instruction
|
|
.set CURRENT_INSTRUCTION, CP_S_S | CP_COMPARE_P_AND_T
|
|
.set OPERATION_TYPE, T_OPERATION
|
|
select_destination destination
|
|
;
|
|
; 29027 registers are not valid destinations for compare operations
|
|
; If the destination is a 29000 register, write the appropriate
|
|
; Boolean value to that register.
|
|
;
|
|
.if ( DESTINATION == DESTINATION_29027 )
|
|
.err
|
|
.print "29027 destinations invalid for compares - @destination@"
|
|
.exitm
|
|
.else
|
|
perform_single_operation destination, operand1, operand2
|
|
cp_read_flags destination
|
|
srl destination, destination, CP_GREATER_THAN_FLAG_POSITION
|
|
sll destination, destination, 31
|
|
.endif
|
|
|
|
.else
|
|
;
|
|
; For 29000 mode (the default) just invoke the trap-inducing instruction
|
|
;
|
|
fgt destination,operand1,operand2
|
|
|
|
.endif
|
|
|
|
.endm ; end of mfgt macro definition
|
|
|
|
;
|
|
; SMART MACRO: mdeq
|
|
;
|
|
; FUNCTION: Double precision, floating point compare
|
|
;
|
|
; PARAMETERS: destination - one of the possible destinations
|
|
; operand1 - one of the possible sources
|
|
; operand2 - one of the possible sources
|
|
;
|
|
.macro mdeq, destination, operand1, operand2
|
|
|
|
.if $narg!=3
|
|
.err
|
|
.print "mdeq: missing parameter(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
|
|
.ifdef _29027_MODE
|
|
;
|
|
; Generate in line 29027 code
|
|
;
|
|
initialize_previous_instruction
|
|
.set CURRENT_INSTRUCTION, CP_D_D | CP_COMPARE_P_AND_T
|
|
.set OPERATION_TYPE, T_OPERATION
|
|
select_destination destination
|
|
;
|
|
; 29027 registers are not valid destinations for compare operations
|
|
; If the destination is a 29000 register, write the appropriate
|
|
; Boolean value to that register.
|
|
;
|
|
.if ( DESTINATION == DESTINATION_29027 )
|
|
.err
|
|
.print "29027 destinations invalid for compare - @destination@"
|
|
.exitm
|
|
.else
|
|
perform_double_operation destination, operand1, operand2
|
|
cp_read_flags destination
|
|
srl destination, destination, CP_EQUAL_FLAG_POSITION
|
|
sll destination, destination, 31
|
|
.endif
|
|
.else
|
|
;
|
|
; For 29000 mode (the default) just invoke the trap-inducing instruction
|
|
;
|
|
deq destination,operand1,operand2
|
|
|
|
.endif
|
|
|
|
.endm ; end of mdeq macro definition
|
|
|
|
;
|
|
; SMART MACRO: mdge
|
|
;
|
|
; FUNCTION: Double precision, floating point compare
|
|
;
|
|
; PARAMETERS: destination - one of the possible destinations
|
|
; operand1 - one of the possible sources
|
|
; operand2 - one of the possible sources
|
|
;
|
|
.macro mdge, destination, operand1, operand2
|
|
|
|
.if $narg!=3
|
|
.err
|
|
.print "mdge: missing parameter(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
|
|
.ifdef _29027_MODE
|
|
;
|
|
; Generate in line 29027 code
|
|
;
|
|
initialize_previous_instruction
|
|
.set CURRENT_INSTRUCTION, CP_D_D | CP_COMPARE_P_AND_T
|
|
.set OPERATION_TYPE, T_OPERATION
|
|
select_destination destination
|
|
;
|
|
; 29027 registers are not valid destinations for compare operations
|
|
; If the destination is a 29000 register, write the appropriate
|
|
; Boolean value to that register.
|
|
;
|
|
.if ( DESTINATION == DESTINATION_29027 )
|
|
.err
|
|
.print "29027 destinations invalid for compare - @destination@"
|
|
.exitm
|
|
.else
|
|
perform_double_operation destination, operand1, operand2
|
|
cp_read_flags destination
|
|
and destination, destination, CP_EQUAL_FLAG | CP_GREATER_THAN_FLAG
|
|
cpneq destination, destination, 0x0
|
|
.endif
|
|
.else
|
|
;
|
|
; For 29000 mode (the default) just invoke the trap-inducing instruction
|
|
;
|
|
dge destination,operand1,operand2
|
|
|
|
.endif
|
|
|
|
.endm ; end of mdge macro definition
|
|
|
|
;
|
|
; SMART MACRO: mdgt
|
|
;
|
|
; FUNCTION: Double precision, floating point compare
|
|
;
|
|
; PARAMETERS: destination - one of the possible destinations
|
|
; operand1 - one of the possible sources
|
|
; operand2 - one of the possible sources
|
|
;
|
|
.macro mdgt, destination, operand1, operand2
|
|
|
|
.if $narg!=3
|
|
.err
|
|
.print "mdgt: missing parameter(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
|
|
.ifdef _29027_MODE
|
|
;
|
|
; Generate in line 29027 code
|
|
;
|
|
initialize_previous_instruction
|
|
.set CURRENT_INSTRUCTION, CP_D_D | CP_COMPARE_P_AND_T
|
|
.set OPERATION_TYPE, T_OPERATION
|
|
select_destination destination
|
|
;
|
|
; 29027 registers are not valid destinations for compare operations
|
|
; If the destination is a 29000 register, write the appropriate
|
|
; Boolean value to that register.
|
|
;
|
|
.if ( DESTINATION == DESTINATION_29027 )
|
|
.err
|
|
.print "29027 destinations invalid for compare - @destination@"
|
|
.exitm
|
|
.else
|
|
perform_double_operation destination, operand1, operand2
|
|
cp_read_flags destination
|
|
srl destination, destination, CP_GREATER_THAN_FLAG_POSITION
|
|
sll destination, destination, 31
|
|
.endif
|
|
.else
|
|
;
|
|
; For 29000 mode (the default) just invoke the trap-inducing instruction
|
|
;
|
|
dgt destination,operand1,operand2
|
|
|
|
.endif
|
|
|
|
.endm ; end of mdgt macro definition
|
|
|
|
;
|
|
; MACRO NAME : perform_double_operation
|
|
;
|
|
; FUNCTION : After the instruction base is set up, do the appropriate checking
|
|
; to send the instruction if necessary, send the double-precision
|
|
; operands if necessary, and start the operation
|
|
;
|
|
; PARAMETERS : destination - one of possible destination operands
|
|
; operand1 - one of possible source operands
|
|
; operand2 - one of possible source operands
|
|
;
|
|
.macro perform_double_operation,destination,operand1,operand2
|
|
|
|
.if $narg!=3
|
|
.err
|
|
.print "perform_double_operation: missing parameter(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
;
|
|
; Start defining the instruction
|
|
;
|
|
select_destination destination
|
|
select_P_operand operand1
|
|
select_S_operand operand2
|
|
|
|
write_and_execute_double_operation operand1, operand2
|
|
|
|
.endm ; End of perform_double_operation macro definition
|
|
|
|
;
|
|
; MACRO NAME : perform_single_operation
|
|
;
|
|
; FUNCTION : After the instruction base is set up, do the appropriate checking
|
|
; to send the instruction if necessary, send the single-precision
|
|
; operands if necessary and start the operation
|
|
;
|
|
; PARAMETERS : destination - one of possible destination operands
|
|
; operand1 - one of possible source operands
|
|
; operand2 - one of possible source operands
|
|
;
|
|
.macro perform_single_operation,destination,operand1,operand2
|
|
|
|
;
|
|
; Start defining the instruction
|
|
;
|
|
select_destination destination
|
|
select_P_operand operand1
|
|
select_S_operand operand2
|
|
write_and_execute_single_operation operand1,operand2
|
|
|
|
.endm ; End of perform_single_operation macro definition
|
|
|
|
;
|
|
; MACRO NAME : write_and_execute_double_operation
|
|
;
|
|
; FUNCTION : Write the instruction and operands for a double-precision
|
|
; operation, and start the operation
|
|
;
|
|
; PARAMETER : operand1 - first operand of double-precision operation
|
|
; operand2 - second operand of operation
|
|
;
|
|
.macro write_and_execute_double_operation,operand1,operand2
|
|
.if ( ( R_SOURCE == R_SOURCE_29027 ) && ( S_SOURCE == S_SOURCE_29027 ) )
|
|
;
|
|
; If both sources are within the 29027, write the instruction
|
|
; and start the operation
|
|
;
|
|
const t4, CURRENT_INSTRUCTION
|
|
consth t4, CURRENT_INSTRUCTION
|
|
cp_write_inst t4, START
|
|
.else
|
|
;
|
|
; One or both of the sources must be written first, so check the
|
|
; previous instruction
|
|
;
|
|
const t4, CURRENT_INSTRUCTION
|
|
consth t4, CURRENT_INSTRUCTION
|
|
cp_write_inst t4
|
|
.if ( R_SOURCE == R_SOURCE_29000 ) && ( S_SOURCE == S_SOURCE_29027 )
|
|
.ifeqs "@operand1@","t0"
|
|
cp_write_r t0, t1, START
|
|
.else
|
|
.ifeqs "@operand1@","t2"
|
|
cp_write_r t2, t3, START
|
|
.else
|
|
.ifeqs "@operand1@","rtn0"
|
|
cp_write_r rtn0, rtn1, START
|
|
.else
|
|
.err
|
|
.print "Invalid source for double operation - @operand1@"
|
|
.exitm
|
|
.endif
|
|
.endif
|
|
.endif
|
|
.endif
|
|
.if ( R_SOURCE == R_SOURCE_29027 ) && ( S_SOURCE == S_SOURCE_29000 )
|
|
.ifeqs "@operand2@","t0"
|
|
cp_write_s t0, t1, START
|
|
.else
|
|
.ifeqs "@operand2@","t2"
|
|
cp_write_s t2, t3, START
|
|
.else
|
|
.ifeqs "@operand2@","rtn0"
|
|
cp_write_s rtn0, rtn1, START
|
|
.else
|
|
.err
|
|
.print "Invalid source for double operation - @operand1@"
|
|
.exitm
|
|
.endif
|
|
.endif
|
|
.endif
|
|
.endif
|
|
.if ( R_SOURCE == R_SOURCE_29000 ) && ( S_SOURCE == S_SOURCE_29000 )
|
|
.ifeqs "@operand1@","t0"
|
|
cp_write_r t0, t1
|
|
.else
|
|
.ifeqs "@operand1@","t2"
|
|
cp_write_r t2, t3
|
|
.else
|
|
.ifeqs "@operand1@","rtn0"
|
|
cp_write_r rtn0, rtn1
|
|
.else
|
|
.err
|
|
.print "Invalid source for double operation - @operand1@"
|
|
.exitm
|
|
.endif
|
|
.endif
|
|
.endif
|
|
.ifeqs "@operand2@","t0"
|
|
cp_write_s t0, t1, START
|
|
.else
|
|
.ifeqs "@operand2@","t2"
|
|
cp_write_s t2, t3, START
|
|
.else
|
|
.ifeqs "@operand2@","rtn0"
|
|
cp_write_s rtn0, rtn1, START
|
|
.else
|
|
.err
|
|
.print "Invalid source for double operation - @operand1@"
|
|
.exitm
|
|
.endif
|
|
.endif
|
|
.endif
|
|
.endif
|
|
.endif
|
|
|
|
.endm ; end of write_and_execute_double_operation macro definition
|
|
|
|
;
|
|
; MACRO NAME : write_and_execute_single_operation
|
|
;
|
|
; FUNCTION : If necessary, read the result from the 29027 into a
|
|
; register on the 29000
|
|
;
|
|
; PARAMETER : operand1 - first source for single-precision operation
|
|
; operand2 - second source for operation
|
|
;
|
|
.macro write_and_execute_single_operation,operand1,operand2
|
|
|
|
.if ( ( R_SOURCE == R_SOURCE_29027 ) && ( S_SOURCE == S_SOURCE_29027 ) )
|
|
;
|
|
; If both sources are within the 29027, write the instruction
|
|
; and start the operation
|
|
;
|
|
const t4, CURRENT_INSTRUCTION
|
|
consth t4, CURRENT_INSTRUCTION
|
|
cp_write_inst t4, START
|
|
.else
|
|
;
|
|
; One or both of the sources must be written first, so check the
|
|
; previous instruction
|
|
;
|
|
const t4,CURRENT_INSTRUCTION
|
|
consth t4,CURRENT_INSTRUCTION
|
|
cp_write_inst t4, START
|
|
.if ( R_SOURCE == R_SOURCE_29000 ) && ( S_SOURCE == S_SOURCE_29027 )
|
|
cp_write_r operand1, operand1, START
|
|
.endif
|
|
.if ( R_SOURCE == R_SOURCE_29027 ) && ( S_SOURCE == S_SOURCE_29000 )
|
|
cp_write_s operand2, operand2, START
|
|
.endif
|
|
.if ( R_SOURCE == R_SOURCE_29000 ) && ( S_SOURCE == S_SOURCE_29000 )
|
|
cp_write_rs operand1, operand2, START
|
|
.endif
|
|
.endif
|
|
|
|
.endm ; End of write_and_execute_single_operation macro definition
|
|
|
|
;
|
|
; MACRO NAME : read_double_result
|
|
;
|
|
; FUNCTION : If necessary, read the result from the 29027 into a
|
|
; register on the 29000
|
|
;
|
|
; PARAMETER : destination - one of the possible destination registers
|
|
;
|
|
.macro read_double_result,destination
|
|
.if ( DESTINATION == DESTINATION_29000 )
|
|
;
|
|
; If the destination is not within the 29027 register file, read
|
|
; the result and store it into the correct register in the 29000
|
|
;
|
|
.ifeqs "@destination@","rtn0"
|
|
cp_read_dp rtn0, rtn1
|
|
.else
|
|
.err
|
|
.print "Invalid destination for double result - @destination@"
|
|
.exitm
|
|
.endif
|
|
.endif
|
|
|
|
.endm ; End of read_double_result macro definition
|
|
|
|
;
|
|
; MACRO NAME : read_single_result
|
|
;
|
|
; FUNCTION : If necessary, read the result from the 29027 into a
|
|
; register on the 29000
|
|
;
|
|
; PARAMETER : destination
|
|
;
|
|
.macro read_single_result,destination
|
|
|
|
.if ( DESTINATION == DESTINATION_29000 )
|
|
;
|
|
; If the destination is not within the 29027 register file, read
|
|
; the result and store it into the correct register in the 29000
|
|
;
|
|
.ifeqs "@destination@","rtn0"
|
|
cp_read_sp rtn0
|
|
.else
|
|
.err
|
|
.print "Invalid destination for single result - @destination@"
|
|
.exitm
|
|
.endif
|
|
.endif
|
|
|
|
.endm ; End of read_single_result macro definition
|
|
|
|
;
|
|
; MACRO NAME : read_integer_result
|
|
;
|
|
; FUNCTION : If necessary, read the result from the 29027 into a
|
|
; register on the 29000
|
|
;
|
|
; PARAMETER : destination
|
|
;
|
|
.macro read_integer_result,destination
|
|
|
|
.if ( DESTINATION == DESTINATION_29000 )
|
|
;
|
|
; If the destination is not within the 29027 register file, read
|
|
; the result and store it into the correct register in the 29000
|
|
;
|
|
.ifeqs "@destination@","rtn0"
|
|
cp_read_int rtn0
|
|
.else
|
|
.err
|
|
.print "Invalid destination for single result - @destination@"
|
|
.exitm
|
|
.endif
|
|
.endif
|
|
|
|
.endm ; End of read_integer_result macro definition
|
|
|
|
;
|
|
; MACRO NAME : select_P_operand
|
|
;
|
|
; FUNCTION : Given an operand, determine if the operand is from the
|
|
; register file, and if so, set the appropriate bits in
|
|
; the current instruction word. In addition, set the
|
|
; variable R_SOURCE to 0 for local register file, or 1 for
|
|
; floating-point register file.
|
|
;
|
|
; PARAMETER : operand1 - one of the possible source operands
|
|
;
|
|
.macro select_P_operand,operand1
|
|
.ifeqs "@operand1@","t0"
|
|
.set R_SOURCE,R_SOURCE_29000
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_R
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","t2"
|
|
.set R_SOURCE,R_SOURCE_29000
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_R
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","rtn0"
|
|
.set R_SOURCE,R_SOURCE_29000
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_R
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","FP0"
|
|
.set R_SOURCE,R_SOURCE_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_RF0
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","FP1"
|
|
.set R_SOURCE,R_SOURCE_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_RF1
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","FP2"
|
|
.set R_SOURCE,R_SOURCE_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_RF2
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","FP3"
|
|
.set R_SOURCE,R_SOURCE_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_RF3
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","FP4"
|
|
.set R_SOURCE,R_SOURCE_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_RF4
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","FP5"
|
|
.set R_SOURCE,R_SOURCE_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_RF5
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","FP6"
|
|
.set R_SOURCE,R_SOURCE_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_RF6
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","FP7"
|
|
.set R_SOURCE,R_SOURCE_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_P_EQ_RF7
|
|
.exitm
|
|
.endif
|
|
.err
|
|
.print "@operand1@ - Invalid operand"
|
|
|
|
.endm ; end of select_P_operand macro definition
|
|
|
|
;
|
|
; MACRO NAME : select_S_operand
|
|
;
|
|
; FUNCTION : Given an operand, determine if the operand is from the
|
|
; register file, and if so, set the appropriate bits in
|
|
; the current instruction word. In addition, set the
|
|
; variable S_SOURCE to S_SOURCE_29000 or S_SOURCE_29027
|
|
; as appropriate
|
|
;
|
|
; PARAMETER : operand2 - one of the possible source operands
|
|
;
|
|
.macro select_S_operand,operand2
|
|
.ifeqs "@operand2@","t0"
|
|
.set S_SOURCE,S_SOURCE_29000
|
|
.if ( OPERATION_TYPE == T_OPERATION )
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_S
|
|
.else
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_S
|
|
.endif
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand2@","t2"
|
|
.set S_SOURCE,S_SOURCE_29000
|
|
.if ( OPERATION_TYPE == T_OPERATION )
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_S
|
|
.else
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_S
|
|
.endif
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand2@","rtn0"
|
|
.set S_SOURCE,S_SOURCE_29000
|
|
.if ( OPERATION_TYPE == T_OPERATION )
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_S
|
|
.else
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_S
|
|
.endif
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand2@","FP0"
|
|
.set S_SOURCE,S_SOURCE_29027
|
|
.if ( OPERATION_TYPE == T_OPERATION )
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF0
|
|
.else
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_RF0
|
|
.endif
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand2@","FP1"
|
|
.set S_SOURCE,S_SOURCE_29027
|
|
.if ( OPERATION_TYPE == T_OPERATION )
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF1
|
|
.else
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_RF1
|
|
.endif
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand2@","FP2"
|
|
.set S_SOURCE,S_SOURCE_29027
|
|
.if ( OPERATION_TYPE == T_OPERATION )
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF2
|
|
.else
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_RF2
|
|
.endif
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand2@","FP3"
|
|
.set S_SOURCE,S_SOURCE_29027
|
|
.if ( OPERATION_TYPE == T_OPERATION )
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF3
|
|
.else
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_RF3
|
|
.endif
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand2@","FP4"
|
|
.set S_SOURCE,S_SOURCE_29027
|
|
.if ( OPERATION_TYPE == T_OPERATION )
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF4
|
|
.else
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_RF4
|
|
.endif
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand2@","FP5"
|
|
.set S_SOURCE,S_SOURCE_29027
|
|
.if ( OPERATION_TYPE == T_OPERATION )
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF5
|
|
.else
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_RF5
|
|
.endif
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand2@","FP6"
|
|
.set S_SOURCE,S_SOURCE_29027
|
|
.if ( OPERATION_TYPE == T_OPERATION )
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF6
|
|
.else
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_RF6
|
|
.endif
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand2@","FP7"
|
|
.set S_SOURCE,S_SOURCE_29027
|
|
.if ( OPERATION_TYPE == T_OPERATION )
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF7
|
|
.else
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_Q_EQ_RF7
|
|
.endif
|
|
.exitm
|
|
.endif
|
|
.err
|
|
.print "@operand2@ - Invalid operand"
|
|
|
|
.endm ; end of select_S_operand macro definition
|
|
|
|
;
|
|
; MACRO NAME : select_T_operand
|
|
;
|
|
; FUNCTION : Given an operand, determine if the operand is from the
|
|
; register file, and if so, set the appropriate bits in
|
|
; the current instruction word, to read the corresponding
|
|
; source into the T operand. In addition, set the
|
|
; variable R_SOURCE to 0 for local register file, or 1 for
|
|
; floating-point register file.
|
|
;
|
|
; PARAMETER : operand1 - one of the possible source operands
|
|
;
|
|
.macro select_T_operand,operand1
|
|
.ifeqs "@operand1@","t0"
|
|
.set R_SOURCE,R_SOURCE_29000
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_R
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","t2"
|
|
.set R_SOURCE,R_SOURCE_29000
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_R
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","rtn0"
|
|
.set R_SOURCE,R_SOURCE_29000
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_R
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","FP0"
|
|
.set R_SOURCE,R_SOURCE_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF0
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","FP1"
|
|
.set R_SOURCE,R_SOURCE_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF1
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","FP2"
|
|
.set R_SOURCE,R_SOURCE_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF2
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","FP3"
|
|
.set R_SOURCE,R_SOURCE_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF3
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","FP4"
|
|
.set R_SOURCE,R_SOURCE_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF4
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","FP5"
|
|
.set R_SOURCE,R_SOURCE_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF5
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","FP6"
|
|
.set R_SOURCE,R_SOURCE_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF6
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@operand1@","FP7"
|
|
.set R_SOURCE,R_SOURCE_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_T_EQ_RF7
|
|
.exitm
|
|
.endif
|
|
.err
|
|
.print "@operand1@ - Invalid operand"
|
|
|
|
.endm ; end of select_T_operand macro definition
|
|
|
|
;
|
|
; MACRO NAME : select_destination
|
|
;
|
|
; FUNCTION : Given a destination, determine if the operand is from the
|
|
; register file, and if so, set the appropriate bits in
|
|
; the current instruction word. In addition, set the
|
|
; variable DESTINATION to DESTINATION_29000 or
|
|
; DESTINATION_29027 as appropriate
|
|
;
|
|
; PARAMETER : destination - one of the possible destination operands
|
|
;
|
|
.macro select_destination,destination
|
|
.ifeqs "@destination@","rtn0"
|
|
.set DESTINATION,DESTINATION_29000
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@destination@","FP0"
|
|
.set DESTINATION,DESTINATION_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_DEST_EQ_RF0
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@destination@","FP1"
|
|
.set DESTINATION,DESTINATION_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_DEST_EQ_RF1
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@destination@","FP2"
|
|
.set DESTINATION,DESTINATION_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_DEST_EQ_RF2
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@destination@","FP3"
|
|
.set DESTINATION,DESTINATION_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_DEST_EQ_RF3
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@destination@","FP4"
|
|
.set DESTINATION,DESTINATION_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_DEST_EQ_RF4
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@destination@","FP5"
|
|
.set DESTINATION,DESTINATION_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_DEST_EQ_RF5
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@destination@","FP6"
|
|
.set DESTINATION,DESTINATION_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_DEST_EQ_RF6
|
|
.exitm
|
|
.endif
|
|
.ifeqs "@destination@","FP7"
|
|
.set DESTINATION,DESTINATION_29027
|
|
.set CURRENT_INSTRUCTION, CURRENT_INSTRUCTION | CP_DEST_EQ_RF7
|
|
.exitm
|
|
.endif
|
|
.err
|
|
.print "@destination@ - Invalid operand"
|
|
|
|
.endm ; end of select_destination macro definition
|
|
|
|
; MACRO NAME : initialize_previous_instruction
|
|
;
|
|
; FUNCTION : Make sure the previous instruction is defined and set to zero
|
|
;
|
|
.macro initialize_previous_instruction
|
|
|
|
.ifndef PREVIOUS_INSTRUCTION
|
|
;
|
|
; Make sure that the previous instruction variable is initialized
|
|
;
|
|
.set PREVIOUS_INSTRUCTION,0
|
|
.endif
|
|
|
|
.endm ; end of initialize_previous_instruction macro definition
|
|
|
|
|
|
; MACRO NAME : prepare_function_parameters
|
|
;
|
|
; FUNCTION : To place the input parameters into the correct position for
|
|
; use by the function body. When the target language is
|
|
; FORTRAN, the values of the input arguments are read from the
|
|
; supplied addresses and moved to the t0-t3 temporary area.
|
|
; When the target language is C or Pascal, the values of the
|
|
; input arguments are simply moved to the t0-t3 temporary area.
|
|
;
|
|
.macro prepare_function_parameters,arg1,arg2
|
|
|
|
.if $narg==0
|
|
.err
|
|
.print "Missing function argument(s)"
|
|
.exitm
|
|
.endif
|
|
|
|
.if $narg>2
|
|
.err
|
|
.print "Too many function arguments
|
|
.exitm
|
|
.endif
|
|
|
|
.if $narg>=1
|
|
.if $isreg(@arg1)
|
|
.ifdef FORTRAN
|
|
load 0,0,t0,arg1
|
|
.if ( FUNCTION_TYPE == DOUBLE_FUNCTION )
|
|
add t1,arg1,4
|
|
load 0,0,t1,t1
|
|
.endif
|
|
.else
|
|
add t0,arg1,0
|
|
.if ( FUNCTION_TYPE == DOUBLE_FUNCTION )
|
|
add t1,%%(&arg1+1),0
|
|
.endif
|
|
.endif
|
|
.else
|
|
.err
|
|
.print "Function argument not register - @arg1@"
|
|
.endif
|
|
.endif
|
|
.if $narg==2
|
|
.if $isreg (@arg2)
|
|
.ifdef FORTRAN
|
|
load 0,0,t2,arg2
|
|
.if ( FUNCTION_TYPE == DOUBLE_FUNCTION )
|
|
add t3,arg2,4
|
|
load 0,0,t3,t3
|
|
.endif
|
|
.else
|
|
add t2,arg2,0
|
|
.if ( FUNCTION_TYPE == DOUBLE_FUNCTION )
|
|
add t3,%%(&arg2+1),0
|
|
.endif
|
|
.endif
|
|
.else
|
|
.err
|
|
.print "Function argument not register - @arg2@"
|
|
.endif
|
|
.endif
|
|
|
|
.endm ; end of prepare_function_parameters macro definition
|
|
|
|
; end of smartmac.h file
|