summaryrefslogtreecommitdiff
path: root/src/cmd/5l/softfloat.c
blob: 82874ee1cf5a992e883f76cca5a9a3d5c90f94f6 (plain)
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
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#define	EXTERN
#include	"l.h"

void
softfloat()
{
	Prog *p, *next, *psfloat;
	Sym *symsfloat;
	int wasfloat;
	
	symsfloat = lookup("_sfloat", 0);
	psfloat = P;
	if(symsfloat->type == STEXT)
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT) {
			if(p->from.sym == symsfloat) {
				psfloat = p;
				break;
			}
		}
	}

	wasfloat = 0;
	p = firstp;
	for(p = firstp; p != P; p = p->link) {
		switch(p->as) {
		case AMOVWD:
		case AMOVWF:
		case AMOVDW:
		case AMOVFW:
		case AMOVFD:
		case AMOVDF:
		case AMOVF:
		case AMOVD:
		case ACMPF:
		case ACMPD:
		case AADDF:
		case AADDD:
		case ASUBF:
		case ASUBD:
		case AMULF:
		case AMULD:
		case ADIVF:
		case ADIVD:
			if (psfloat == P)
				diag("floats used with _sfloat not defined");
			if (!wasfloat) {
				next = prg();
				*next = *p;

				// BL		_sfloat(SB)
				*p = zprg;
				p->link = next;
				p->as = ABL;
 				p->to.type = D_BRANCH;
				p->to.sym = symsfloat;
				p->cond = psfloat;

				p = next;
				wasfloat = 1;
			}
			break;
		default:
			wasfloat = 0;
		}
	}
}