📄 intrinsi.h
字号:
; MACRO NAME: extract_Rounding_Mode;; FUNCTION: to extract the Rounding Mode portion of the floating-point; invironment mode register, shift the value to the range of; 0-7, and leave it in a register;; INPUT PARAMETERS: reg - destination for the mode; .macro extract_Rounding_Mode,reg .ifdef _29027_MODE .extern __29027Mode const reg,__29027Mode consth reg,__29027Mode load 0,0,reg,reg srl reg,reg,CP_RMS_POSITION and reg,reg,CP_RMS_MASK >> CP_RMS_POSITION .else mfsr reg,FPE and reg,reg,FPE_FPRND_MASK srl reg,reg,FPE_FPRND_POSITION .endif .endm;; MACRO NAME: set_Rounding_Mode;; FUNCTION: to set the 29027 Rounding Mode to a given value;; INPUT PARAMETERS: reg - working register; reg2 - second working register; rounding_mode - value of the rounding mode; 0 - round to nearest; 1 - round to minus infinity; 2 - round to plus infinity; 3 - round to zero;; NOTES: rounding_mode value is not checked; 29027 Mode register is NOT written by this macro; .macro set_Rounding_Mode,reg,reg2,mode .ifdef _29027_MODE .extern __29027Mode const reg2,__29027Mode consth reg2,__29027Mode load 0,0,reg,reg2 const reg2,CP_RMS_MASK consth reg2,CP_RMS_MASK andn reg,reg,reg2 const reg2,mode sll reg2,reg2,CP_RMS_POSITION or reg,reg,reg2 const reg2,__29027Mode consth reg2,__29027Mode store 0,0,reg,reg2 add reg2,reg2,4 load 0,0,reg2,reg2 cp_write_mode reg2,reg .else mfsr reg,FPE andn reg,reg,FPE_FPRND_MASK const reg2,mode sll reg2,reg2,FPE_FPRND_POSITION or reg,reg,reg2 mtsr FPE,reg .endif .endm;;; NOTE: The 29027 is the floating point coprocessor for the 29000.; It contains 8 floating point registers FP0 to FP7. Three of ; these, FP0, FP1, and FP2, are currently designated as scratch,; that is, they will not be preserved across calls. The other ; five contain values that must be saved whenever they are used ; in code, and restored before the exit of the routine. The 29027 ; registers are tagged with a single bit indicating the precision ; of the current value. When numbers are read into the 29027,; they are always stored in double precision, so that single ; precision values are converted on input. Only the MOVE instruction; fails to do this automatic widening. If the result from calculations; in the 29027 ALU (determined by the result precision bit in the ; instruction word) is to be single precision and the result saved in; an FP reg, the result precision bit from the instruction gets copied; into the precision bit for the register. If a single precision; SNaN is saved from the 29027, it will be converted to a double; precision QNaN. Along the way it will cause an unmasked exception; when read off the chip and cause changes to the status register.; So the preservation routine will need to modify the mode register to ; mask off the exceptions, save the state of the status register before; saving the FP regs, and restore the status and mode registers to their; original settings when the save is complete.;; REFERENCE: The instructions to drive the Am29027 are described in the; Am29027 manual beginning on page 17. Table 4 describes the ; operation codes and table 3 the multiplexer codes. Communication; with the 29000 is described on pages 11 and 12 of the Am29027; manual and chapters 6 and 8 of the Am29000 User's Manual;; MACRO NAME: save_FP_regs;; FUNCTION: to save the AMD 29027 floating point register values in the; 29000 general purpose registers;; INPUT PARAMETERS: fp_register, one of the 29027 registers FP3 - FP7;; REGISTER USAGE: the following registers are used in save_FP_regs;; rtn0 this register is used in setting the mode and status registers; rtn1 this register is used in setting the mode and status registers; rtn6 this register is used to store the MSW when FP3 is saved; rtn7 this register is used to store the LSW when FP3 is saved; rtn8 this register is used to store the MSW when FP4 is saved; rtn9 this register is used to store the LSW when FP4 is saved; .macro save_FP_regs,fp_register .ifdef _29027_MODE ; ; For 29027 mode, expand the macro into 29027 code to preserve FP register ; .ifeqs "@fp_register@","FP3" const rtn6,__29027Mode ; Load the address of FP mode consth rtn6,__29027Mode load 0,0,rtn0,rtn6 ; Load MSW of FP mode into rtn0 add rtn6,rtn6,4 ; Increment rtn6 + 4 load 0,0,rtn1,rtn6 ; Load LSW of FP mode into rtn1 const rtn6,CP_RESERVED_OP_EXCP_MASK ; Load mask to disable exception consth rtn6,CP_RESERVED_OP_EXCP_MASK or rtn0,rtn0,rtn6 ; OR in disable of exception mask cp_write_mode rtn1, rtn0 ; Reset mode w/exception disabled cp_read_status rtn0 ; Read status and save in rtn1 const rtn6,CP_PASS_P | CP_P_EQ_RF3 ; Instruction is PASS_P from RF3 consth rtn6,CP_PASS_P | CP_P_EQ_RF3 ; Load & execute the instruction ; store 1,CP_WRITE_INST | CP_START,rtn6,rtn6 load 1,CP_READ_MSBS,rtn6,rtn6 ; Read the MSW to first register load 1,CP_READ_LSBS,rtn7,rtn7 ; Read the LSW to second register cp_write_status rtn0 ; Restore the original status const rtn1,__29027Mode ; Load the address of FP mode consth rtn1,__29027Mode load 0,0,rtn0,rtn1 ; Load MSW of FP mode into rtn0 add rtn1,rtn1,4 ; Increment rtn6 to __29027Mode+4 load 0,0,rtn1,rtn1 ; Load LSW of FP mode into rtn1 cp_write_mode rtn1, rtn0 ; Restore the original write mode .endif .ifeqs "@fp_register@","FP4" const rtn8,__29027Mode ; Load the address of FP mode consth rtn8,__29027Mode load 0,0,rtn0,rtn8 ; Load MSW of FP mode into rtn0 add rtn8,rtn8,4 ; Increment rtn6 + 4 load 0,0,rtn1,rtn8 ; Load LSW of FP mode into rtn1 const rtn8,CP_RESERVED_OP_EXCP_MASK ; Load mask to disable exception consth rtn8,CP_RESERVED_OP_EXCP_MASK or rtn0,rtn0,rtn8 ; OR in disable of exception mask cp_write_mode rtn1, rtn0 ; Reset mode w/exception disabled cp_read_status rtn0 ; Read status and save in rtn1 const rtn8,CP_PASS_P | CP_P_EQ_RF4 ; Instruction is PASS_P from RF4 consth rtn8,CP_PASS_P | CP_P_EQ_RF4 ; Load & execute the instruction ; store 1,CP_WRITE_INST | CP_START,rtn8,rtn8 load 1,CP_READ_MSBS,rtn8,rtn8 ; Read the MSW to first register load 1,CP_READ_LSBS,rtn9,rtn9 ; Read the LSW to second register cp_write_status rtn0 ; Restore the original status const rtn1,__29027Mode ; Load the address of FP mode consth rtn1,__29027Mode load 0,0,rtn0,rtn1 ; Load MSW of FP mode into rtn0 add rtn1,rtn1,4 ; Increment rtn6 + 4 load 0,0,rtn1,rtn1 ; Load LSW of FP mode into rtn1 cp_write_mode rtn1, rtn0 ; Restore the original write mode .endif .else ; ; For 29000 mode, do nothing ; .endif .endm;; MACRO NAME: restore_FP_regs;; FUNCTION: to restore the AMD 29027 floating point register values from the; 29000 general purpose registers;; INPUT PARAMETERS: fp_register, one of the 29027 registers FP3 - FP7;; REGISTER USAGE: the following registers are used in restore_FP_regs;; rtn0 this register is used in setting the mode and status registers; rtn6 the value in this register is stored as the MSW of FP3 ; rtn7 the value in this register is stored as the LSW of FP3 ; rtn8 the value in this register is stored as the MSW of FP4 ; rtn9 the value in this register is stored as the LSW of FP4 ; .macro restore_FP_regs,fp_register .ifdef _29027_MODE ; ; For 29027 mode, move data from return registers to the correct FP register ; .ifeqs "@fp_register@","FP3" store 1,CP_WRITE_R ,rtn6,rtn7 ; Move the data to the R register ; Then create the instruction ; const rtn0,CP_MOVE_P|CP_D_D|CP_P_EQ_R|CP_DEST_EQ_RF3 consth rtn0,CP_MOVE_P|CP_D_D|CP_P_EQ_R|CP_DEST_EQ_RF3 ; ; Perform the write ; store 1,(CP_WRITE_INST | CP_START),rtn0,0 .endif .ifeqs "@fp_register@","FP4" store 1,CP_WRITE_R ,rtn8,rtn9 ; Move the data to the R register ; Then create the instruction ; const rtn0,CP_MOVE_P|CP_D_D|CP_P_EQ_R|CP_DEST_EQ_RF4 consth rtn0,CP_MOVE_P|CP_D_D|CP_P_EQ_R|CP_DEST_EQ_RF4 ; ; Perform the write ; store 1,(CP_WRITE_INST | CP_START),rtn0,0 .endif .else ; ; For 29000 mode, do nothing. ; .endif .endm; ; end of file intrinsi.h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -