Blame view

kernel/linux-imx6_3.14.28/arch/m68k/fpsp040/smovecr.S 4.19 KB
6b13f685e   김민수   BSP 최초 추가
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