Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
58ee1f5d
Commit
58ee1f5d
authored
Oct 28, 2009
by
Kai Backman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
shift for non-64 bit integers.
R=rsc
http://go/go-review/1015017
parent
e3fd2e1e
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
97 additions
and
3 deletions
+97
-3
cgen.c
src/cmd/5g/cgen.c
+5
-2
gg.h
src/cmd/5g/gg.h
+1
-0
ggen.c
src/cmd/5g/ggen.c
+89
-0
gsubr.c
src/cmd/5g/gsubr.c
+1
-0
ggen.c
src/cmd/8g/ggen.c
+1
-1
No files found.
src/cmd/5g/cgen.c
View file @
58ee1f5d
...
...
@@ -244,11 +244,14 @@ cgen(Node *n, Node *res)
// asymmetric binary
case
OSUB
:
case
OLSH
:
case
ORSH
:
a
=
optoas
(
n
->
op
,
nl
->
type
);
goto
abop
;
case
OLSH
:
case
ORSH
:
cgen_shift
(
n
->
op
,
nl
,
nr
,
res
);
break
;
case
OCONV
:
if
(
eqtype
(
n
->
type
,
nl
->
type
)
||
noconv
(
n
->
type
,
nl
->
type
))
{
cgen
(
nl
,
res
);
...
...
src/cmd/5g/gg.h
View file @
58ee1f5d
...
...
@@ -102,6 +102,7 @@ Prog* gshift(int as, Node *lhs, int32 stype, int32 sval, Node *rhs);
Prog
*
gregshift
(
int
as
,
Node
*
lhs
,
int32
stype
,
Node
*
reg
,
Node
*
rhs
);
void
naddr
(
Node
*
,
Addr
*
,
int
);
void
cgen_aret
(
Node
*
,
Node
*
);
void
cgen_shift
(
int
,
Node
*
,
Node
*
,
Node
*
);
/*
* cgen64.c
...
...
src/cmd/5g/ggen.c
View file @
58ee1f5d
...
...
@@ -536,6 +536,95 @@ samereg(Node *a, Node *b)
return
1
;
}
/*
* generate shift according to op, one of:
* res = nl << nr
* res = nl >> nr
*/
void
cgen_shift
(
int
op
,
Node
*
nl
,
Node
*
nr
,
Node
*
res
)
{
Node
n1
,
n2
,
n3
,
t
;
int
w
;
Prog
*
p1
,
*
p2
,
*
p3
;
uvlong
sc
;
if
(
nl
->
type
->
width
>
4
)
fatal
(
"cgen_shift %T"
,
nl
->
type
);
w
=
nl
->
type
->
width
*
8
;
if
(
nr
->
op
==
OLITERAL
)
{
regalloc
(
&
n1
,
nl
->
type
,
res
);
cgen
(
nl
,
&
n1
);
sc
=
mpgetfix
(
nr
->
val
.
u
.
xval
);
if
(
sc
==
0
)
{
return
;
}
else
if
(
sc
>=
nl
->
type
->
width
*
8
)
{
if
(
op
==
ORSH
&&
issigned
[
nl
->
type
->
etype
])
gshift
(
AMOVW
,
&
n1
,
SHIFT_AR
,
w
,
&
n1
);
else
gins
(
AEOR
,
&
n1
,
&
n1
);
}
else
{
if
(
op
==
ORSH
&&
issigned
[
nl
->
type
->
etype
])
gshift
(
AMOVW
,
&
n1
,
SHIFT_AR
,
sc
,
&
n1
);
else
if
(
op
==
ORSH
)
gshift
(
AMOVW
,
&
n1
,
SHIFT_LR
,
sc
,
&
n1
);
else
// OLSH
gshift
(
AMOVW
,
&
n1
,
SHIFT_LL
,
sc
,
&
n1
);
}
gmove
(
&
n1
,
res
);
regfree
(
&
n1
);
return
;
}
if
(
nl
->
ullman
>=
nr
->
ullman
)
{
regalloc
(
&
n2
,
nl
->
type
,
res
);
cgen
(
nl
,
&
n2
);
regalloc
(
&
n1
,
nr
->
type
,
N
);
cgen
(
nr
,
&
n1
);
}
else
{
regalloc
(
&
n1
,
nr
->
type
,
N
);
cgen
(
nr
,
&
n1
);
regalloc
(
&
n2
,
nl
->
type
,
res
);
cgen
(
nl
,
&
n2
);
}
// test for shift being 0
p1
=
gins
(
AMOVW
,
&
n1
,
&
n1
);
p1
->
scond
|=
C_SBIT
;
p3
=
gbranch
(
ABEQ
,
T
);
// test and fix up large shifts
regalloc
(
&
n3
,
nr
->
type
,
N
);
nodconst
(
&
t
,
types
[
TUINT32
],
w
);
gmove
(
&
t
,
&
n3
);
gcmp
(
ACMP
,
&
n1
,
&
n3
);
if
(
op
==
ORSH
)
{
if
(
issigned
[
nl
->
type
->
etype
])
{
p1
=
gshift
(
AMOVW
,
&
n2
,
SHIFT_AR
,
w
-
1
,
&
n2
);
p2
=
gregshift
(
AMOVW
,
&
n2
,
SHIFT_AR
,
&
n1
,
&
n2
);
}
else
{
p1
=
gins
(
AEOR
,
&
n2
,
&
n2
);
p2
=
gregshift
(
AMOVW
,
&
n2
,
SHIFT_LR
,
&
n1
,
&
n2
);
}
p1
->
scond
=
C_SCOND_HS
;
p2
->
scond
=
C_SCOND_LO
;
}
else
{
p1
=
gins
(
AEOR
,
&
n2
,
&
n2
);
p2
=
gregshift
(
AMOVW
,
&
n2
,
SHIFT_LL
,
&
n1
,
&
n2
);
p1
->
scond
=
C_SCOND_HS
;
p2
->
scond
=
C_SCOND_LO
;
}
regfree
(
&
n3
);
patch
(
p3
,
pc
);
gmove
(
&
n2
,
res
);
regfree
(
&
n1
);
regfree
(
&
n2
);
}
void
clearfat
(
Node
*
nl
)
{
...
...
src/cmd/5g/gsubr.c
View file @
58ee1f5d
...
...
@@ -923,6 +923,7 @@ raddr(Node *n, Prog *p)
}
/* generate a comparison
TODO(kaib): one of the args can actually be a small constant. relax the constraint and fix call sites.
*/
Prog
*
gcmp
(
int
as
,
Node
*
lhs
,
Node
*
rhs
)
...
...
src/cmd/8g/ggen.c
View file @
58ee1f5d
...
...
@@ -627,7 +627,7 @@ cgen_shift(int op, Node *nl, Node *nr, Node *res)
uvlong
sc
;
if
(
nl
->
type
->
width
>
4
)
fatal
(
"cgen_shift %T"
,
nl
->
type
->
width
);
fatal
(
"cgen_shift %T"
,
nl
->
type
);
w
=
nl
->
type
->
width
*
8
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment