diff options
author | Christopher Faylor <cgf@redhat.com> | 2000-02-17 19:39:46 +0000 |
---|---|---|
committer | Christopher Faylor <cgf@redhat.com> | 2000-02-17 19:39:46 +0000 |
commit | 6d491d8ad9122891d1a48447e8c49702eb678921 (patch) | |
tree | 45619a131b9f211ceca9fce7a866328344bf00ec /newlib/libc/sys/a29khif/sys/smartmac.h | |
parent | bd592806f45307757c24ec3f75bdefe13abfd51f (diff) | |
download | gdb-cvs/SNAPSHOT.tar.gz |
import newlib-2000-02-17 snapshotcvs/SNAPSHOT
Diffstat (limited to 'newlib/libc/sys/a29khif/sys/smartmac.h')
-rw-r--r-- | newlib/libc/sys/a29khif/sys/smartmac.h | 1491 |
1 files changed, 1491 insertions, 0 deletions
diff --git a/newlib/libc/sys/a29khif/sys/smartmac.h b/newlib/libc/sys/a29khif/sys/smartmac.h new file mode 100644 index 00000000000..2c870fa2a1e --- /dev/null +++ b/newlib/libc/sys/a29khif/sys/smartmac.h @@ -0,0 +1,1491 @@ +; @(#)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 |