Commit f229c8b5 authored by Ken Thompson's avatar Ken Thompson

identical complex implementation

for 6g and 8g. can also be used
for 5g. 5g is still a stub.

R=rsc
CC=golang-dev
https://golang.org/cl/362041
parent 5b1a196c
......@@ -38,3 +38,6 @@ clean:
install: $(TARG)
cp $(TARG) "$(GOBIN)"/$(TARG)
%.$O: ../gc/%.c
$(CC) $(CFLAGS) -c -I. -o $@ ../gc/$*.c
......@@ -134,12 +134,12 @@ void nodfconst(Node*, Type*, Mpflt*);
* cplx.c
*/
int complexop(Node*, Node*);
void complexmove(Node*, Node*, int);
void complexmove(Node*, Node*);
void complexgen(Node*, Node*);
void complexbool(int, Node*, Node*, int, Prog*);
/*
* obj.c
* gobj.c
*/
void datastring(char*, int, Addr*);
......
......@@ -483,7 +483,7 @@ gmove(Node *f, Node *t)
cvt = t->type;
if(iscomplex[ft] || iscomplex[tt]) {
complexmove(f, t, 0);
complexmove(f, t);
return;
}
......
......@@ -22,6 +22,7 @@ OFILES=\
gsubr.$O\
cgen.$O\
cgen64.$O\
cplx.$O\
peep.$O\
reg.$O\
......@@ -38,3 +39,6 @@ clean:
install: $(TARG)
cp $(TARG) "$(GOBIN)"/$(TARG)
%.$O: ../gc/%.c
$(CC) $(CFLAGS) -c -I. -o $@ ../gc/$*.c
......@@ -57,12 +57,6 @@ cgen(Node *n, Node *res)
if(res == N || res->type == T)
fatal("cgen: res nil");
// TODO compile complex
if(n != N && n->type != T && iscomplex[n->type->etype])
return;
if(res != N && res->type != T && iscomplex[res->type->etype])
return;
// inline slices
if(cgen_inline(n, res))
return;
......@@ -98,6 +92,12 @@ cgen(Node *n, Node *res)
break;
}
// complex types
if(complexop(n, res)) {
complexgen(n, res);
return;
}
// if both are addressable, move
if(n->addable && res->addable) {
gmove(n, res);
......@@ -741,12 +741,6 @@ bgen(Node *n, int true, Prog *to)
nl = n->left;
nr = n->right;
// TODO compile complex
if(nl != N && nl->type != T && iscomplex[nl->type->etype])
return;
if(nr != N && nr->type != T && iscomplex[nr->type->etype])
return;
if(n->type == T) {
convlit(&n, types[TBOOL]);
if(n->type == T)
......@@ -857,6 +851,7 @@ bgen(Node *n, int true, Prog *to)
break;
}
a = brcom(a);
true = !true;
}
// make simplest on right
......@@ -960,6 +955,10 @@ bgen(Node *n, int true, Prog *to)
patch(gbranch(optoas(a, nr->type), T), to);
break;
}
if(iscomplex[nl->type->etype]) {
complexbool(a, nl, nr, true, to);
break;
}
if(is64(nr->type)) {
if(!nl->addable) {
......
......@@ -157,6 +157,14 @@ void split64(Node*, Node*, Node*);
void splitclean(void);
void nswap(Node*, Node*);
/*
* cplx.c
*/
int complexop(Node*, Node*);
void complexmove(Node*, Node*);
void complexgen(Node*, Node*);
void complexbool(int, Node*, Node*, int, Prog*);
/*
* gobj.c
*/
......
......@@ -1059,6 +1059,11 @@ gmove(Node *f, Node *t)
tt = simsimtype(t->type);
cvt = t->type;
if(iscomplex[ft] || iscomplex[tt]) {
complexmove(f, t);
return;
}
// cannot have two integer memory operands;
// except 64-bit, which always copies via registers anyway.
if(isint[ft] && isint[tt] && !is64(f->type) && !is64(t->type) && ismem(f) && ismem(t))
......@@ -1489,13 +1494,13 @@ gmove(Node *f, Node *t)
// on the floating point stack. So toss it away here.
// Also, F0 is the *only* register we ever evaluate
// into, so we should only see register/register as F0/F0.
if(ismem(f) && ismem(t))
goto hard;
if(f->op == OREGISTER && t->op == OREGISTER) {
if(f->val.u.reg != D_F0 || t->val.u.reg != D_F0)
goto fatal;
return;
}
if(ismem(f) && ismem(t))
goto hard;
a = AFMOVF;
if(ft == TFLOAT64)
a = AFMOVD;
......@@ -1509,6 +1514,8 @@ gmove(Node *f, Node *t)
break;
case CASE(TFLOAT32, TFLOAT64):
if(ismem(f) && ismem(t))
goto hard;
if(f->op == OREGISTER && t->op == OREGISTER) {
if(f->val.u.reg != D_F0 || t->val.u.reg != D_F0)
goto fatal;
......@@ -1521,6 +1528,8 @@ gmove(Node *f, Node *t)
return;
case CASE(TFLOAT64, TFLOAT32):
if(ismem(f) && ismem(t))
goto hard;
if(f->op == OREGISTER && t->op == OREGISTER) {
tempname(&r1, types[TFLOAT32]);
gins(AFMOVFP, f, &r1);
......
......@@ -79,6 +79,7 @@ char *runtimeimport =
"func \"\".uint64mod (? uint64, ? uint64) uint64\n"
"func \"\".float64toint64 (? float64) int64\n"
"func \"\".int64tofloat64 (? int64) float64\n"
"func \"\".complex128div (num complex128, den complex128) (quo complex128)\n"
"\n"
"$$\n";
char *unsafeimport =
......
This diff is collapsed.
......@@ -101,3 +101,5 @@ func int64mod(int64, int64) int64
func uint64mod(uint64, uint64) uint64
func float64toint64(float64) int64
func int64tofloat64(int64) float64
func complex128div(num complex128, den complex128) (quo complex128)
......@@ -851,13 +851,22 @@ walkexpr(Node **np, NodeList **init)
case ODIV:
case OMOD:
walkexpr(&n->left, init);
walkexpr(&n->right, init);
/*
* rewrite complex div into function call.
*/
et = n->left->type->etype;
if(iscomplex[et] && n->op == ODIV) {
n = mkcall("complex128div", n->type, init,
conv(n->left, types[TCOMPLEX128]),
conv(n->right, types[TCOMPLEX128]));
goto ret;
}
/*
* rewrite div and mod into function calls
* on 32-bit architectures.
*/
walkexpr(&n->left, init);
walkexpr(&n->right, init);
et = n->left->type->etype;
if(widthptr > 4 || (et != TUINT64 && et != TINT64))
goto ret;
if(et == TINT64)
......
......@@ -48,6 +48,7 @@ OFILES=\
chan.$O\
closure.$O\
float.$O\
complex.$O\
hashmap.$O\
iface.$O\
malloc.$O\
......
// Copyright 2010 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 "runtime.h"
// complex128div(num, den complex128) (quo complex128)
void
·complex128div(float64 numreal, float64 numimag,
float64 denreal, float64 denimag,
float64 quoreal, float64 quoimag)
{
float64 a, b, ratio, denom;
a = denreal;
if(a < 0)
a = -a;
b = denimag;
if(b < 0)
b = -b;
if(a <= b) {
if(b == 0)
throw("complex divide");
ratio = denreal/denimag;
denom = denreal*ratio + denimag;
quoreal = (numreal*ratio + numimag) / denom;
quoimag = (numimag*ratio - numreal) / denom;
} else {
ratio = denimag/denreal;
denom = denimag*ratio + denreal;
quoreal = (numimag*ratio + numreal) / denom;
quoimag = (numimag - numreal*ratio) / denom;
}
FLUSH(&quoreal);
FLUSH(&quoimag);
}
......@@ -56,6 +56,25 @@ Hello World!
== ken/
=========== ken/cplx0.go
(+5.000000e+000+6.000000e+000i)
(+5.000000e+000+6.000000e+000i)
(+5.000000e+000+6.000000e+000i)
(+5.000000e+000+6.000000e+000i)
=========== ken/cplx3.go
(+1.292308e+000-1.384615e-001i)
(+1.292308e+000-1.384615e-001i)
64
=========== ken/cplx4.go
c = (-5.000000-6.000000i)
c = (5.000000+6.000000i)
c = (5.000000+6.000000i)
c = (5.000000+6.000000i)
c = (5+6i)
c = (13+7i)
=========== ken/intervar.go
print 1 bio 2 file 3 -- abc
......
// true
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2009 The Go Authors. All rights reserved.
// Copyright 2010 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.
......
// [ $GOARCH != amd64 ] || ($G $D/$F.go && $L $F.$A && ./$A.out)
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2009 The Go Authors. All rights reserved.
// Copyright 2010 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.
......
// [ $GOARCH != amd64 ] || ($G $D/$F.go && $L $F.$A && ./$A.out)
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2009 The Go Authors. All rights reserved.
// Copyright 2010 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.
......
// true
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2009 The Go Authors. All rights reserved.
// Copyright 2010 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.
......@@ -20,7 +20,7 @@ var complexBits = reflect.Typeof(complex(0i)).Size() * 8
func main() {
c0 := C1
c0 = (c0+c0+c0) / (c0+c0)
c0 = (c0+c0+c0) / (c0+c0+3i)
println(c0)
c := *(*complex)(unsafe.Pointer(&c0))
......
// true
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2009 The Go Authors. All rights reserved.
// Copyright 2010 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.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment