mirror of https://github.com/aamine/cbc
* 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:
parent
744e790e5d
commit
cd988128cc
16
ChangeLog
16
ChangeLog
|
@ -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
4
ToDo
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(); }
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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(); }
|
||||
|
||||
|
|
17
test/cast.cb
17
test/cast.cb
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue