* net/loveruby/cflat/compiler/CodeGenerator.java: implement cast.

* net/loveruby/cflat/asm/Assembler.java: new method #movsx, #movzx.
* net/loveruby/cflat/type/PointerType.java: provide #isSigned for cast.
* net/loveruby/cflat/type/ArrayType.java: ditto.
* net/loveruby/cflat/type/UserType.java: ditto.
* test: test cast operation.


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@3995 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2008-09-06 15:59:02 +00:00
parent 744e790e5d
commit cd988128cc
15 changed files with 158 additions and 13 deletions

View File

@ -1,3 +1,19 @@
Sun Sep 7 00:58:49 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/CodeGenerator.java: implement cast.
* net/loveruby/cflat/asm/Assembler.java: new method #movsx,
#movzx.
* net/loveruby/cflat/type/PointerType.java: provide #isSigned for
cast.
* net/loveruby/cflat/type/ArrayType.java: ditto.
* net/loveruby/cflat/type/UserType.java: ditto.
* test: test cast operation.
Sat Sep 6 23:19:48 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/ast/Entity.java (alignment): fetch value from

4
ToDo
View File

@ -2,7 +2,7 @@
== Current
* remove FIXME from Entity.java
* use %rax for address calculation
* prohibit multi-dimension array without size
* dump UTF-8 string byte by byte.
* simple vararg retrieve (get vararg address)
@ -210,3 +210,5 @@
- duplicated import did not propagate symbols
- test if static function is really static
- test switch stmt
- remove FIXME from Entity.java
- implement cast

View File

@ -163,10 +163,14 @@ public class Assembler {
}
protected String addSuffix(String op, Type t) {
return op + typeSuffix(t);
}
protected String typeSuffix(Type t) {
switch ((int)t.size()) {
case 1: return op + "b";
case 2: return op + "w";
case 4: return op + "l";
case 1: return "b";
case 2: return "w";
case 4: return "l";
default:
throw new Error("unknown type size: " + t.size());
}
@ -258,6 +262,10 @@ public class Assembler {
typedOp(type, "mov", src, dest);
}
public void movsx(Type from, Type to, AsmEntity src, AsmEntity dest) {
op("movs" + typeSuffix(from) + typeSuffix(to), src, dest);
}
public void movsbl(AsmEntity src, AsmEntity dest) {
op("movsbl", src, dest);
}
@ -266,6 +274,10 @@ public class Assembler {
op("movswl", src, dest);
}
public void movzx(Type from, Type to, AsmEntity src, AsmEntity dest) {
op("movz" + typeSuffix(from) + typeSuffix(to), src, dest);
}
public void movzb(Type type, AsmEntity src, AsmEntity dest) {
typedOp(type, "movzb", src, dest);
}

View File

@ -688,8 +688,21 @@ static public void p(String s) { System.err.println(s); }
}
public void visit(CastNode node) {
// FIXME: insert cast op here
compile(node.expr());
Type src = node.expr().type();
Type dest = node.type();
// We need not execute downcast because we can cast big value
// to small value by just cutting off higer bits.
if (dest.size() > src.size()) {
if (src.isSigned()) {
movsx(src, dest,
reg("ax").forType(src), reg("ax").forType(dest));
}
else {
movzx(src, dest,
reg("ax").forType(src), reg("ax").forType(dest));
}
}
}
public void visit(VariableNode node) {
@ -933,6 +946,8 @@ comment("compileLHS: }");
public void ret() { as.ret(); }
public void mov(AsmEntity src, AsmEntity dest) { as.mov(src, dest); }
public void mov(Type type, AsmEntity src, AsmEntity dest) { as.mov(type, src, dest); }
public void movsx(Type from, Type to, AsmEntity src, AsmEntity dest) { as.movsx(from, to, src, dest); }
public void movzx(Type from, Type to, AsmEntity src, AsmEntity dest) { as.movzx(from, to, src, dest); }
public void movsbl(AsmEntity src, AsmEntity dest) { as.movsbl(src, dest); }
public void movswl(AsmEntity src, AsmEntity dest) { as.movswl(src, dest); }
public void movzb(Type type, AsmEntity src, AsmEntity dest) { as.movzb(type, src, dest); }

View File

@ -23,6 +23,7 @@ public class ArrayType extends Type {
public boolean isDereferable() { return true; }
public boolean isPointerAlike() { return isUnallocatedArray(); }
public boolean isScalar() { return true; }
public boolean isSigned() { return false; }
public Type baseType() {
return baseType;

View File

@ -12,6 +12,7 @@ public class PointerType extends Type {
public boolean isPointer() { return true; }
public boolean isPointerAlike() { return true; }
public boolean isScalar() { return true; }
public boolean isSigned() { return false; }
public boolean isDereferable() { return true; }
public boolean isCallable() { return baseType.isFunction(); }

View File

@ -4,13 +4,13 @@ import net.loveruby.cflat.exception.*;
public abstract class Type {
static final public long sizeUnknown = -1;
abstract public long size();
public long allocSize() { return size(); }
public long alignment() {
return size();
}
abstract public long size();
public long allocSize() { return size(); }
abstract public boolean isSameType(Type other);
public boolean isVoid() { return false; }
@ -22,9 +22,9 @@ public abstract class Type {
public boolean isArray() { return false; }
public boolean isAllocatedArray() { return false; }
public boolean isUnallocatedArray() { return false; }
public boolean isComplexType() { return false; }
public boolean isStruct() { return false; }
public boolean isUnion() { return false; }
public boolean isComplexType() { return false; }
public boolean isUserType() { return false; }
public boolean isFunction() { return false; }

View File

@ -22,13 +22,18 @@ public class UserType extends NamedType {
// Forward methods to real type.
//
public long alignment() { return realType().alignment(); }
public long size() { return realType().size(); }
public long allocSize() { return realType().allocSize(); }
public long alignment() { return realType().alignment(); }
public boolean isVoid() { return realType().isVoid(); }
public boolean isInt() { return realType().isInt(); }
public boolean isInteger() { return realType().isInteger(); }
public boolean isSigned() { return realType().isSigned(); }
public boolean isPointer() { return realType().isPointer(); }
public boolean isArray() { return realType().isArray(); }
public boolean isAllocatedArray() { return realType().isAllocatedArray(); }
public boolean isUnallocatedArray() { return realType().isUnallocatedArray(); }
public boolean isComplexType() { return realType().isComplexType(); }
public boolean isStruct() { return realType().isStruct(); }
public boolean isUnion() { return realType().isUnion(); }
@ -36,7 +41,9 @@ public class UserType extends NamedType {
public boolean isFunction() { return realType().isFunction(); }
public boolean isDereferable() { return realType().isDereferable(); }
public boolean isPointerAlike() { return realType().isPointerAlike(); }
public boolean isCallable() { return realType().isCallable(); }
public boolean isScalar() { return realType().isScalar(); }
public Type baseType() { return realType().baseType(); }

View File

@ -4,6 +4,21 @@ int
main(int argc, char **argv)
{
short n = 5000;
printf("%ld\n", (long)((long)n * (long)n));
char a = 1;
char b = -1;
short c = 1;
short d = -1;
printf("%ld", ((long)n * (long)n));
printf(";%d", (int)a);
printf(";%ld", (long)a);
printf(";%d", (int)b);
printf(";%ld", (long)b);
printf(";%d", (int)c);
printf(";%ld", (long)c);
printf(";%d", (int)d);
printf(";%ld", (long)d);
puts("");
return 0;
}

18
test/charops2.cb Normal file
View File

@ -0,0 +1,18 @@
import stdio;
int
main(int argc, char **argv)
{
char i = -1;
i <<= 1;
printf("%hhd", i);
i <<= 5;
printf(";%hhd", i);
i <<= 1;
printf(";%hhd", i);
i <<= 1;
printf(";%hhd", i);
puts("");
return 0;
}

View File

@ -7,7 +7,7 @@ main(int argc, char **argv)
i <<= 1;
printf("%hd", i);
i <<= (short)13;
i <<= 13;
printf(";%hd", i);
i <<= 1;
printf(";%hd", i);

18
test/shortops2.cb Normal file
View File

@ -0,0 +1,18 @@
import stdio;
int
main(int argc, char **argv)
{
short i = -1;
i <<= 1;
printf("%hd", i);
i <<= 13;
printf(";%hd", i);
i <<= 1;
printf(";%hd", i);
i <<= 1;
printf(";%hd", i);
puts("");
return 0;
}

View File

@ -196,9 +196,13 @@ test_22_pointer() {
test_23_limits() {
assert_out "2;64;-128;0" ./charops
assert_out "-2;-64;-128;0" ./charops2
assert_out "2;64;128;0" ./ucharops
assert_out "254;192;128;0" ./ucharops2
assert_out "2;16384;-32768;0" ./shortops
assert_out "-2;-16384;-32768;0" ./shortops2
assert_out "2;16384;32768;0" ./ushortops
assert_out "65534;49152;32768;0" ./ushortops2
assert_out "2;1073741824;-2147483648;0" ./intops
assert_out "2;1073741824;2147483648;0" ./uintops
assert_out "1;2;1073741824;-2147483648;0" ./longops # 32bit
@ -206,7 +210,7 @@ test_23_limits() {
}
test_24_cast() {
assert_out "25000000" ./cast
assert_out "25000000;1;1;-1;-1;1;1;-1;-1" ./cast
assert_out "777;666" ./cast2
}

18
test/ucharops2.cb Normal file
View File

@ -0,0 +1,18 @@
import stdio;
int
main(int argc, char **argv)
{
unsigned char i = -1;
i <<= 1;
printf("%hhu", i);
i <<= 5;
printf(";%hhu", i);
i <<= 1;
printf(";%hhu", i);
i <<= 1;
printf(";%hhu", i);
puts("");
return 0;
}

18
test/ushortops2.cb Normal file
View File

@ -0,0 +1,18 @@
import stdio;
int
main(int argc, char **argv)
{
unsigned short i = -1;
i <<= 1;
printf("%hu", i);
i <<= 13;
printf(";%hu", i);
i <<= 1;
printf(";%hu", i);
i <<= 1;
printf(";%hu", i);
puts("");
return 0;
}