Skip to content
This repository has been archived by the owner on May 2, 2018. It is now read-only.

Commit

Permalink
more on type complex.
Browse files Browse the repository at this point in the history
getting close.

R=rsc
CC=golang-dev
https://golang.org/cl/224105
  • Loading branch information
ken committed Mar 3, 2010
1 parent 305f543 commit 7d4b1e4
Show file tree
Hide file tree
Showing 11 changed files with 442 additions and 10 deletions.
17 changes: 10 additions & 7 deletions src/cmd/6g/cgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ cgen(Node *n, Node *res)
break;
}

if(complexop(n, res)) {
complexgen(n, res);
goto ret;
}

if(n->addable) {
gmove(n, res);
goto ret;
Expand All @@ -134,13 +139,6 @@ cgen(Node *n, Node *res)
goto ret;
}

// complex ops are special.
if(iscomplex[n->type->etype] || iscomplex[res->type->etype] ||
n->left != N && iscomplex[n->left->type->etype]) {
complexgen(n, res);
goto ret;
}

a = optoas(OAS, n->type);
if(sudoaddable(a, n, &addr)) {
if(res->op == OREGISTER) {
Expand Down Expand Up @@ -802,6 +800,7 @@ bgen(Node *n, int true, Prog *to)
goto ret;
}
a = brcom(a);
true = !true;
}

// make simplest on right
Expand Down Expand Up @@ -849,6 +848,10 @@ bgen(Node *n, int true, Prog *to)
regfree(&n1);
break;
}
if(iscomplex[nl->type->etype]) {
complexbool(a, nl, nr, true, to);
break;
}

if(nr->ullman >= UINF) {
regalloc(&n1, nr->type, N);
Expand Down
122 changes: 119 additions & 3 deletions src/cmd/6g/cplx.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ complexmove(Node *f, Node *t, int perm)
int ft, tt;
Node n1, n2, n3, n4, nc;

if(1||debug['g']) {
if(debug['g']) {
dump("\ncomplex-f", f);
dump("complex-t", t);
}
Expand Down Expand Up @@ -113,6 +113,28 @@ complexmove(Node *f, Node *t, int perm)
}
}

int
complexop(Node *n, Node *res)
{
if(n != N && n->type != T)
if(iscomplex[n->type->etype]) {
switch(n->op) {
case OCONV:
case OADD:
case OSUB:
case OMUL:
case ODIV:
case OMINUS:
goto yes;
}
//dump("complexop no", n);
}
return 0;

yes:
return 1;
}

void
complexgen(Node *n, Node *res)
{
Expand All @@ -121,7 +143,7 @@ complexgen(Node *n, Node *res)
Node ra, rb, rc, rd;
int tl, tr;

if(1||debug['g']) {
if(debug['g']) {
dump("\ncomplex-n", n);
dump("complex-res", res);
}
Expand Down Expand Up @@ -257,10 +279,104 @@ complexgen(Node *n, Node *res)
complexmove(nl, res, 2);
break;
}
fatal("opcode %O", n->op);

subnode(&n1, &n2, nl);
subnode(&n3, &n4, nr);
subnode(&n5, &n6, res);

regalloc(&ra, n5.type, N);
regalloc(&rb, n5.type, N);
regalloc(&rc, n6.type, N);
regalloc(&rd, n6.type, N);

gmove(&n1, &ra);
gmove(&n3, &rc);
gins(optoas(OMUL, n5.type), &rc, &ra); // ra = a*c

gmove(&n2, &rb);
gmove(&n4, &rd);
gins(optoas(OMUL, n5.type), &rd, &rb); // rb = b*d
gins(optoas(OADD, n5.type), &rb, &ra); // ra = (a*c + b*d)

gins(optoas(OMUL, n5.type), &n2, &rc); // rc = b*c
gins(optoas(OMUL, n5.type), &n1, &rd); // rd = a*d
gins(optoas(OSUB, n5.type), &rd, &rc); // rc = (b*c - a*d)

gmove(&n3, &rb);
gins(optoas(OMUL, n5.type), &rb, &rb); // rb = c*c
gmove(&n4, &rd);
gins(optoas(OMUL, n5.type), &rd, &rd); // rd = d*d
gins(optoas(OADD, n5.type), &rd, &rb); // rb = (c*c + d*d)

gins(optoas(ODIV, n5.type), &rb, &ra); // ra = (a*c + b*d)/(c*c + d*d)
gins(optoas(ODIV, n5.type), &rb, &rc); // rc = (b*c - a*d)/(c*c + d*d)

gmove(&ra, &n5);
gmove(&rc, &n6);

regfree(&ra);
regfree(&rb);
regfree(&rc);
regfree(&rd);
break;
}
}

void
complexbool(int op, Node *nl, Node *nr, int true, Prog *to)
{
Node n1, n2, n3, n4;
Node na, nb, nc;

// make both sides addable in ullman order
if(nr != N) {
if(nl->ullman > nr->ullman && !nl->addable) {
tempname(&n1, nl->type);
complexgen(nl, &n1);
nl = &n1;
}
if(!nr->addable) {
tempname(&n2, nr->type);
complexgen(nr, &n2);
nr = &n2;
}
}
if(!nl->addable) {
tempname(&n1, nl->type);
complexgen(nl, &n1);
nl = &n1;
}

// build tree
// real(l) == real(r) && imag(l) == imag(r)

subnode(&n1, &n2, nl);
subnode(&n3, &n4, nr);

memset(&na, 0, sizeof(na));
na.op = OANDAND;
na.left = &nb;
na.right = &nc;
na.type = types[TBOOL];

memset(&nb, 0, sizeof(na));
nb.op = OEQ;
nb.left = &n1;
nb.right = &n3;
nb.type = types[TBOOL];

memset(&nc, 0, sizeof(na));
nc.op = OEQ;
nc.left = &n2;
nc.right = &n4;
nc.type = types[TBOOL];

if(op == ONE)
true = !true;

bgen(&na, true, to);
}

int
cplxsubtype(int et)
{
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/6g/gg.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,10 @@ void nodfconst(Node*, Type*, Mpflt*);
/*
* cplx.c
*/
int complexop(Node*, Node*);
void complexmove(Node*, Node*, int);
void complexgen(Node*, Node*);
void complexbool(int, Node*, Node*, int, Prog*);

/*
* obj.c
Expand Down
7 changes: 7 additions & 0 deletions src/cmd/6g/gsubr.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,11 @@ regalloc(Node *n, Type *t, Node *o)
goto out;
yyerror("out of floating registers");
goto err;

case TCOMPLEX64:
case TCOMPLEX128:
tempname(n, t);
return;
}
yyerror("regalloc: unknown type %T", t);

Expand All @@ -305,6 +310,8 @@ regfree(Node *n)
{
int i;

if(n->op == ONAME && iscomplex[n->type->etype])
return;
if(n->op != OREGISTER && n->op != OINDREG)
fatal("regfree: not a register");
i = n->val.u.reg;
Expand Down
6 changes: 6 additions & 0 deletions src/cmd/gc/gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,12 @@ cgen_as(Node *nl, Node *nr)
nr->val.ctype = CTNIL;
break;

case TCOMPLEX64:
case TCOMPLEX128:
nr->val.u.cval = mal(sizeof(*nr->val.u.cval));
mpmovecflt(&nr->val.u.cval->real, 0.0);
mpmovecflt(&nr->val.u.cval->imag, 0.0);
break;
}
nr->op = OLITERAL;
nr->type = tl;
Expand Down
21 changes: 21 additions & 0 deletions src/pkg/reflect/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,21 @@ type FloatType struct {
commonType
}

// Complex64Type represents a complex64 type.
type Complex64Type struct {
commonType
}

// Complex128Type represents acomplex128 type.
type Complex128Type struct {
commonType
}

// ComplexType represents a complex type.
type ComplexType struct {
commonType
}

// Int16Type represents an int16 type.
type Int16Type struct {
commonType
Expand Down Expand Up @@ -585,6 +600,12 @@ func toType(i interface{}) Type {
return (*Float32Type)(unsafe.Pointer(v))
case *runtime.Float64Type:
return (*Float64Type)(unsafe.Pointer(v))
case *runtime.ComplexType:
return (*ComplexType)(unsafe.Pointer(v))
case *runtime.Complex64Type:
return (*Complex64Type)(unsafe.Pointer(v))
case *runtime.Complex128Type:
return (*Complex128Type)(unsafe.Pointer(v))
case *runtime.IntType:
return (*IntType)(unsafe.Pointer(v))
case *runtime.Int8Type:
Expand Down
63 changes: 63 additions & 0 deletions src/pkg/reflect/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,63 @@ func (v *Float64Value) Set(x float64) {
// Set sets v to the value x.
func (v *Float64Value) SetValue(x Value) { v.Set(x.(*Float64Value).Get()) }

//// ComplexValue represents a complex value.
//type ComplexValue struct {
// value
//}
//
//// Get returns the underlying complex value.
//func (v *ComplexValue) Get() complex { return *(*complex)(v.addr) }
//
//// Set sets v to the value x.
//func (v *ComplexValue) Set(x complex) {
// if !v.canSet {
// panic(cannotSet)
// }
// *(*complex)(v.addr) = x
//}
//
//// Set sets v to the value x.
//func (v *ComplexValue) SetValue(x Value) { v.Set(x.(*ComplexValue).Get()) }
//
//// Complex64Value represents a complex64 value.
//type Complex64Value struct {
// value
//}
//
//// Get returns the underlying complex64 value.
//func (v *Complex64Value) Get() complex64 { return *(*complex64)(v.addr) }
//
//// Set sets v to the value x.
//func (v *Complex64Value) Set(x complex64) {
// if !v.canSet {
// panic(cannotSet)
// }
// *(*complex64)(v.addr) = x
//}
//
//// Set sets v to the value x.
//func (v *Complex64Value) SetValue(x Value) { v.Set(x.(*Complex64Value).Get()) }
//
//// Complex128Value represents a complex128 value.
//type Complex128Value struct {
// value
//}
//
//// Get returns the underlying complex128 value.
//func (v *Complex128Value) Get() complex128 { return *(*complex128)(v.addr) }
//
//// Set sets v to the value x.
//func (v *Complex128Value) Set(x complex128) {
// if !v.canSet {
// panic(cannotSet)
// }
// *(*complex128)(v.addr) = x
//}
//
//// Set sets v to the value x.
//func (v *Complex128Value) SetValue(x Value) { v.Set(x.(*Complex128Value).Get()) }

// IntValue represents an int value.
type IntValue struct {
value
Expand Down Expand Up @@ -1246,6 +1303,12 @@ func newValue(typ Type, addr addr, canSet bool) Value {
return (*Float32Value)(v)
case *Float64Type:
return (*Float64Value)(v)
// case *ComplexType:
// return (*ComplexValue)(v)
// case *Complex64Type:
// return (*Complex64Value)(v)
// case *Complex128Type:
// return (*Complex128Value)(v)
case *IntType:
return (*IntValue)(v)
case *Int8Type:
Expand Down
6 changes: 6 additions & 0 deletions test/golden.out
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ 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/intervar.go
print 1 bio 2 file 3 -- abc

Expand Down
28 changes: 28 additions & 0 deletions test/ken/cplx0.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// $G $D/$F.go && $L $F.$A && ./$A.out

// 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.

package main

const (
R = 5
I = 6i

C1 = R + I // ADD(5,6)
)

func doprint(c complex) { println(c) }

func main() {

// constants
println(C1)
doprint(C1)

// variables
c1 := C1
println(c1)
doprint(c1)
}
Loading

0 comments on commit 7d4b1e4

Please sign in to comment.