| // 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: |
| 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 = next; |
| wasfloat = 1; |
| } |
| break; |
| |
| notsoft: |
| wasfloat = 0; |
| } |
| } |
| } |
| } |