Prog *p1, *p2;
uint32 w;
uint64 v;
+ int r;
if(debug['g']) {
dump("\nagen-res", res);
break;
case OCALLMETH:
- cgen_callmeth(n, 0);
+ case OCALLFUNC:
+ // Release res so that it is available for cgen_call.
+ // Pick it up again after the call.
+ r = -1;
+ if(n->ullman >= UINF) {
+ if(res->op == OREGISTER || res->op == OINDREG) {
+ r = res->val.u.reg;
+ reg[r]--;
+ }
+ }
+ if(n->op == OCALLMETH)
+ cgen_callmeth(n, 0);
+ else
+ cgen_call(n, 0);
+ if(r >= 0)
+ reg[r]++;
cgen_aret(n, res);
break;
cgen_aret(n, res);
break;
- case OCALLFUNC:
- cgen_call(n, 0);
- cgen_aret(n, res);
- break;
-
case OINDEX:
p2 = nil; // to be patched to panicindex.
w = n->type->width;
ptxt = gins(ATEXT, curfn->nname, &nod1);
afunclit(&ptxt->from);
+ ginit();
genlist(curfn->enter);
pret = nil;
}
genlist(curfn->nbody);
+ gclean();
checklabels();
if(nerrors != 0)
goto ret;
if(pret)
patch(pret, pc);
+ ginit();
if(hasdefer)
ginscall(deferreturn, 0);
if(curfn->exit)
genlist(curfn->exit);
+ gclean();
if(nerrors != 0)
goto ret;
if(curfn->endlineno)
void
cgen_callinter(Node *n, Node *res, int proc)
{
+ int r;
Node *i, *f;
Node tmpi, nodo, nodr, nodsp;
i = i->left; // interface
+ // Release res register during genlist and cgen,
+ // which might have their own function calls.
+ r = -1;
+ if(res != N && (res->op == OREGISTER || res->op == OINDREG)) {
+ r = res->val.u.reg;
+ reg[r]--;
+ }
+
if(!i->addable) {
tempname(&tmpi, i->type);
cgen(i, &tmpi);
}
genlist(n->list); // args
+ if(r >= 0)
+ reg[r]++;
regalloc(&nodr, types[tptr], res);
regalloc(&nodo, types[tptr], &nodr);
cgen(nl, &n1);
sc = mpgetfix(nr->val.u.xval);
if(sc == 0) {
- return;
+ // nothing to do
} else if(sc >= nl->type->width*8) {
if(op == ORSH && issigned[nl->type->etype])
gshift(AMOVW, &n1, SHIFT_AR, w, &n1);
}
}
+static int resvd[] =
+{
+ 9, // reserved for m
+ 10, // reserved for g
+};
+
+void
+ginit(void)
+{
+ int i;
+
+ for(i=0; i<nelem(reg); i++)
+ reg[i] = 0;
+ for(i=0; i<nelem(resvd); i++)
+ reg[resvd[i]]++;
+}
+
+void
+gclean(void)
+{
+ int i;
+
+ for(i=0; i<nelem(resvd); i++)
+ reg[resvd[i]]--;
+
+ for(i=0; i<nelem(reg); i++)
+ if(reg[i])
+ yyerror("reg %R left allocated\n", i);
+}
+
int32
anyregalloc(void)
{
+ int i, j;
+
+ for(i=0; i<nelem(reg); i++) {
+ if(reg[i] == 0)
+ goto ok;
+ for(j=0; j<nelem(resvd); j++)
+ if(resvd[j] == i)
+ goto ok;
+ return 1;
+ ok:;
+ }
return 0;
}
{
int i, et, fixfree, floatfree;
- // guarantee R9 and R10 (m and g) are left alone. BUG.
- reg[9] = 1;
- reg[10] = 1;
if(debug['r']) {
fixfree = 0;
for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++)
Prog *scontin, *sbreak;
Prog *p1, *p2, *p3;
Label *lab;
+ int32 wasregalloc;
lno = setlineno(n);
+ wasregalloc = anyregalloc();
if(n == N)
goto ret;
}
ret:
+ if(anyregalloc() != wasregalloc) {
+ dump("node", n);
+ fatal("registers left allocated");
+ }
+
lineno = lno;
}
}
func (err WrongValueError) String() string {
- // BUG: work around bug in 5g by simplifying expression.
- // return "huffmanBitWriter: " + err.name + " should belong to [" + strconv.Itoa64(int64(err.from)) + ";" +
- // strconv.Itoa64(int64(err.to)) + "] but actual value is " + strconv.Itoa64(int64(err.value))
- str := "huffmanBitWriter: " + err.name + " should belong to ["
- str += strconv.Itoa64(int64(err.from)) + ";"
- str += strconv.Itoa64(int64(err.to)) + "] but actual value is "
- str += strconv.Itoa64(int64(err.value))
- return str
+ return "huffmanBitWriter: " + err.name + " should belong to [" + strconv.Itoa64(int64(err.from)) + ";" +
+ strconv.Itoa64(int64(err.to)) + "] but actual value is " + strconv.Itoa64(int64(err.value))
}
func (w *huffmanBitWriter) flushBits() {
continue
}
if !dec.compatibleType(localField.Type, wireField.id) {
- // BUG: work around bug in 5g by simplifying expression.
- // return nil, os.ErrorString("gob: wrong type (" +
- // localField.Type.String() + ") for received field " +
- // wireStruct.name + "." + wireField.name)
- str := "gob: wrong type ("
- str += localField.Type.String() + ") for received field "
- str += wireStruct.name + "." + wireField.name
- return nil, os.ErrorString(str)
+ return nil, os.ErrorString("gob: wrong type (" +
+ localField.Type.String() + ") for received field " +
+ wireStruct.name + "." + wireField.name)
}
op, indir, err := dec.decOpFor(wireField.id, localField.Type, localField.Name)
if err != nil {
if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 {
t := time.SecondsToLocalTime(ns / 1e9)
if l.flag&(Ldate) != 0 {
- // BUG: work around bug in 5g by simplifying expression.
- // h += itoa(int(t.Year), 4) + "/" + itoa(t.Month, 2) + "/" + itoa(t.Day, 2) + " "
- h += itoa(int(t.Year), 4)
- h += "/" + itoa(t.Month, 2)
- h += "/" + itoa(t.Day, 2) + " "
+ h += itoa(int(t.Year), 4) + "/" + itoa(t.Month, 2) + "/" + itoa(t.Day, 2) + " "
}
if l.flag&(Ltime|Lmicroseconds) != 0 {
h += itoa(t.Hour, 2) + ":" + itoa(t.Minute, 2) + ":" + itoa(t.Second, 2)
// If IPv4, use dotted notation.
if p4 := p.To4(); len(p4) == 4 {
- // BUG: work around bug in 5g by simplifying expression.
- // return itod(uint(p4[0])) + "." +
- // itod(uint(p4[1])) + "." +
- // itod(uint(p4[2])) + "." +
- // itod(uint(p4[3]))
- str := itod(uint(p4[0])) + "."
- str += itod(uint(p4[1])) + "."
- str += itod(uint(p4[2])) + "."
- str += itod(uint(p4[3]))
- return str
+ return itod(uint(p4[0])) + "." +
+ itod(uint(p4[1])) + "." +
+ itod(uint(p4[2])) + "." +
+ itod(uint(p4[3]))
}
if len(p) != IPv6len {
return "?"
// String is the string representation of a ParseError.
func (e *ParseError) String() string {
if e.Message == "" {
- // BUG: work around bug in 5g by simplifying expression.
- // return "parsing time " +
- // strconv.Quote(e.Value) + " as " +
- // strconv.Quote(e.Layout) + ": cannot parse " +
- // strconv.Quote(e.ValueElem) + " as " +
- // strconv.Quote(e.LayoutElem)
- str := "parsing time " + strconv.Quote(e.Value) + " as "
- str += strconv.Quote(e.Layout) + ": cannot parse "
- str += strconv.Quote(e.ValueElem) + " as "
- str += strconv.Quote(e.LayoutElem)
- return str
+ return "parsing time " +
+ strconv.Quote(e.Value) + " as " +
+ strconv.Quote(e.Layout) + ": cannot parse " +
+ strconv.Quote(e.ValueElem) + " as " +
+ strconv.Quote(e.LayoutElem)
}
return "parsing time " +
strconv.Quote(e.Value) + e.Message
p.err = p.syntaxError("element <" + s.name.Local + "> closed by </" + name.Local + ">")
return false
case s.name.Space != name.Space:
- // BUG: work around bug in 5g by simplifying expression.
- // p.err = p.syntaxError("element <" + s.name.Local + "> in space " + s.name.Space +
- // "closed by </" + name.Local + "> in space " + name.Space)
- str := "element <" + s.name.Local
- str += "> in space " + s.name.Space
- str += "closed by </" + name.Local
- str += "> in space " + name.Space
- p.err = p.syntaxError(str)
+ p.err = p.syntaxError("element <" + s.name.Local + "> in space " + s.name.Space +
+ "closed by </" + name.Local + "> in space " + name.Space)
return false
}