hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
|    smovecr.sa 3.1 12/10/90
|
|    The entry point sMOVECR returns the constant at the
|    offset given in the instruction field.
|
|    Input: An offset in the instruction word.
|
|    Output:    The constant rounded to the user's rounding
|        mode unchecked for overflow.
|
|    Modified: fp0.
|
|
|        Copyright (C) Motorola, Inc. 1990
|            All Rights Reserved
|
|       For details on the license for this file, please see the
|       file, README, in this same directory.
 
|SMOVECR    idnt    2,1 | Motorola 040 Floating Point Software Package
 
   |section 8
 
#include "fpsp.h"
 
   |xref    nrm_set
   |xref    round
   |xref    PIRN
   |xref    PIRZRM
   |xref    PIRP
   |xref    SMALRN
   |xref    SMALRZRM
   |xref    SMALRP
   |xref    BIGRN
   |xref    BIGRZRM
   |xref    BIGRP
 
FZERO:    .long    00000000
|
|    FMOVECR
|
   .global    smovcr
smovcr:
   bfextu    CMDREG1B(%a6){#9:#7},%d0 |get offset
   bfextu    USER_FPCR(%a6){#26:#2},%d1 |get rmode
|
| check range of offset
|
   tstb    %d0        |if zero, offset is to pi
   beqs    PI_TBL        |it is pi
   cmpib    #0x0a,%d0        |check range $01 - $0a
   bles    Z_VAL        |if in this range, return zero
   cmpib    #0x0e,%d0        |check range $0b - $0e
   bles    SM_TBL        |valid constants in this range
   cmpib    #0x2f,%d0        |check range $10 - $2f
   bles    Z_VAL        |if in this range, return zero
   cmpib    #0x3f,%d0        |check range $30 - $3f
   ble    BG_TBL        |valid constants in this range
Z_VAL:
   fmoves    FZERO,%fp0
   rts
PI_TBL:
   tstb    %d1        |offset is zero, check for rmode
   beqs    PI_RN        |if zero, rn mode
   cmpib    #0x3,%d1        |check for rp
   beqs    PI_RP        |if 3, rp mode
PI_RZRM:
   leal    PIRZRM,%a0    |rmode is rz or rm, load PIRZRM in a0
   bra    set_finx
PI_RN:
   leal    PIRN,%a0        |rmode is rn, load PIRN in a0
   bra    set_finx
PI_RP:
   leal    PIRP,%a0        |rmode is rp, load PIRP in a0
   bra    set_finx
SM_TBL:
   subil    #0xb,%d0        |make offset in 0 - 4 range
   tstb    %d1        |check for rmode
   beqs    SM_RN        |if zero, rn mode
   cmpib    #0x3,%d1        |check for rp
   beqs    SM_RP        |if 3, rp mode
SM_RZRM:
   leal    SMALRZRM,%a0    |rmode is rz or rm, load SMRZRM in a0
   cmpib    #0x2,%d0        |check if result is inex
   ble    set_finx    |if 0 - 2, it is inexact
   bra    no_finx        |if 3, it is exact
SM_RN:
   leal    SMALRN,%a0    |rmode is rn, load SMRN in a0
   cmpib    #0x2,%d0        |check if result is inex
   ble    set_finx    |if 0 - 2, it is inexact
   bra    no_finx        |if 3, it is exact
SM_RP:
   leal    SMALRP,%a0    |rmode is rp, load SMRP in a0
   cmpib    #0x2,%d0        |check if result is inex
   ble    set_finx    |if 0 - 2, it is inexact
   bra    no_finx        |if 3, it is exact
BG_TBL:
   subil    #0x30,%d0        |make offset in 0 - f range
   tstb    %d1        |check for rmode
   beqs    BG_RN        |if zero, rn mode
   cmpib    #0x3,%d1        |check for rp
   beqs    BG_RP        |if 3, rp mode
BG_RZRM:
   leal    BIGRZRM,%a0    |rmode is rz or rm, load BGRZRM in a0
   cmpib    #0x1,%d0        |check if result is inex
   ble    set_finx    |if 0 - 1, it is inexact
   cmpib    #0x7,%d0        |second check
   ble    no_finx        |if 0 - 7, it is exact
   bra    set_finx    |if 8 - f, it is inexact
BG_RN:
   leal    BIGRN,%a0    |rmode is rn, load BGRN in a0
   cmpib    #0x1,%d0        |check if result is inex
   ble    set_finx    |if 0 - 1, it is inexact
   cmpib    #0x7,%d0        |second check
   ble    no_finx        |if 0 - 7, it is exact
   bra    set_finx    |if 8 - f, it is inexact
BG_RP:
   leal    BIGRP,%a0    |rmode is rp, load SMRP in a0
   cmpib    #0x1,%d0        |check if result is inex
   ble    set_finx    |if 0 - 1, it is inexact
   cmpib    #0x7,%d0        |second check
   ble    no_finx        |if 0 - 7, it is exact
|    bra    set_finx    ;if 8 - f, it is inexact
set_finx:
   orl    #inx2a_mask,USER_FPSR(%a6) |set inex2/ainex
no_finx:
   mulul    #12,%d0            |use offset to point into tables
   movel    %d1,L_SCR1(%a6)        |load mode for round call
   bfextu    USER_FPCR(%a6){#24:#2},%d1    |get precision
   tstl    %d1            |check if extended precision
|
| Precision is extended
|
   bnes    not_ext            |if extended, do not call round
   fmovemx (%a0,%d0),%fp0-%fp0        |return result in fp0
   rts
|
| Precision is single or double
|
not_ext:
   swap    %d1            |rnd prec in upper word of d1
   addl    L_SCR1(%a6),%d1        |merge rmode in low word of d1
   movel    (%a0,%d0),FP_SCR1(%a6)    |load first word to temp storage
   movel    4(%a0,%d0),FP_SCR1+4(%a6)    |load second word
   movel    8(%a0,%d0),FP_SCR1+8(%a6)    |load third word
   clrl    %d0            |clear g,r,s
   lea    FP_SCR1(%a6),%a0
   btstb    #sign_bit,LOCAL_EX(%a0)
   sne    LOCAL_SGN(%a0)        |convert to internal ext. format
 
   bsr    round            |go round the mantissa
 
   bfclr    LOCAL_SGN(%a0){#0:#8}    |convert back to IEEE ext format
   beqs    fin_fcr
   bsetb    #sign_bit,LOCAL_EX(%a0)
fin_fcr:
   fmovemx (%a0),%fp0-%fp0
   rts
 
   |end