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
162
|
|
| 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
|
| THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
| The copyright notice above does not evidence any
| actual or intended publication of such source code.
|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
|