1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 #define EXTERN
6 #include "l.h"
7 #include "../ld/lib.h"
8
9 // Software floating point.
10
11 void
12 softfloat(void)
13 {
14 Prog *p, *next, *psfloat;
15 Sym *symsfloat;
16 int wasfloat;
17
18 if(!debug['F'])
19 return;
20
21 symsfloat = lookup("_sfloat", 0);
22 psfloat = P;
23 if(symsfloat->type == STEXT)
24 psfloat = symsfloat->text;
25
26 for(cursym = textp; cursym != nil; cursym = cursym->next) {
27 wasfloat = 0;
28 for(p = cursym->text; p != P; p = p->link)
29 if(p->cond != P)
30 p->cond->mark |= LABEL;
31 for(p = cursym->text; p != P; p = p->link) {
32 switch(p->as) {
33 case AMOVW:
34 if(p->to.type == D_FREG || p->from.type == D_FREG)
35 goto soft;
36 goto notsoft;
37
38 case AMOVWD:
39 case AMOVWF:
40 case AMOVDW:
41 case AMOVFW:
42 case AMOVFD:
43 case AMOVDF:
44 case AMOVF:
45 case AMOVD:
46
47 case ACMPF:
48 case ACMPD:
49 case AADDF:
50 case AADDD:
51 case ASUBF:
52 case ASUBD:
53 case AMULF:
54 case AMULD:
55 case ADIVF:
56 case ADIVD:
57 case ASQRTF:
58 case ASQRTD:
59 goto soft;
60
61 default:
62 goto notsoft;
63
64 soft:
65 if (psfloat == P)
66 diag("floats used with _sfloat not defined");
67 if (!wasfloat || (p->mark&LABEL)) {
68 next = prg();
69 *next = *p;
70
71 // BL _sfloat(SB)
72 *p = zprg;
73 p->link = next;
74 p->as = ABL;
75 p->to.type = D_BRANCH;
76 p->to.sym = symsfloat;
77 p->cond = psfloat;
78
79 p = next;
80 wasfloat = 1;
81 }
82 break;
83
84 notsoft:
85 wasfloat = 0;
86 }
87 }
88 }
89 }