// 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. #include "l.h" #include "../ld/lib.h" // Software floating point. void softfloat(void) { Prog *p, *next, *psfloat; Sym *symsfloat; int wasfloat; if(!debug['F']) return; symsfloat = lookup("_sfloat", 0); psfloat = P; if(symsfloat->type == STEXT) psfloat = symsfloat->text; for(cursym = textp; cursym != nil; cursym = cursym->next) { wasfloat = 0; for(p = cursym->text; p != P; p = p->link) if(p->cond != P) p->cond->mark |= LABEL; for(p = cursym->text; p != P; p = p->link) { switch(p->as) { case AMOVW: if(p->to.type == D_FREG || p->from.type == D_FREG) goto soft; goto notsoft; 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: case ASQRTF: case ASQRTD: case AABSF: case AABSD: goto soft; default: goto notsoft; soft: if (psfloat == P) diag("floats used with _sfloat not defined"); if (!wasfloat || (p->mark&LABEL)) { 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->line = next->line; p = next; wasfloat = 1; } break; notsoft: wasfloat = 0; } } } }