summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNagi5Yeq <wu@x-nagi.com>2020-06-01 21:34:58 +0800
committerNagi5Yeq <wu@x-nagi.com>2020-06-01 21:34:58 +0800
commitcd1466f30c146e12faa0db7e1b53b508bf2274c6 (patch)
treed938d02d17bbf4949b0dc1d21dee861afe171bdc
parentf90115fba35887aea8d4064b57f4909cd6937134 (diff)
64 bit support
-rw-r--r--Lexer.l3
-rw-r--r--Parser.y7
-rw-r--r--Type.cc24
-rw-r--r--Type.hh9
-rw-r--r--TypeManager.cc16
-rw-r--r--TypeManager.hh3
-rw-r--r--node/ExprNode.cc8
-rw-r--r--node/LiteralNode.hh2
-rw-r--r--t/extern.pas2
-rw-r--r--t/sha1.pas10
10 files changed, 64 insertions, 20 deletions
diff --git a/Lexer.l b/Lexer.l
index caaf43d..be168f3 100644
--- a/Lexer.l
+++ b/Lexer.l
@@ -119,6 +119,7 @@ comment {comment1}|{comment2}|{comment3}
"boolean" {return Parser::make_BOOLEAN(loc);}
"char" {return Parser::make_CHAR(loc);}
"integer" {return Parser::make_INTEGER(loc);}
+"int64" {return Parser::make_INT64(loc);}
"real" {return Parser::make_REAL(loc);}
"string" {return Parser::make_STRING(loc);}
"array" {return Parser::make_ARRAY(loc);}
@@ -129,7 +130,7 @@ comment {comment1}|{comment2}|{comment3}
"false" {return Parser::make_BOOLEAN_LITERAL(false, loc);}
{integer} {
- int number = std::strtol(yytext, NULL, 0);
+ long long number = std::strtoll(yytext, NULL, 0);
return Parser::make_INTEGER_LITERAL(number, loc);
}
diff --git a/Parser.y b/Parser.y
index f4e9779..429e88d 100644
--- a/Parser.y
+++ b/Parser.y
@@ -45,7 +45,7 @@ YY_DECL;
%token COLON SEMICOLON COMMA DOTDOT DOT ASSIGN LBRACKET RBRACKET LPARENTHESIS RPARENTHESIS
%token PROGRAM IDENTIFIER VAR CONST TYPE BEGINS ENDS FUNCTION EXTERN DOTDOTDOT
%token IF THEN ELSE WHILE DO REPEAT UNTIL BREAK CONTINUE FOR TO
-%token VOID BOOLEAN CHAR INTEGER REAL STRING ARRAY OF RECORD
+%token VOID BOOLEAN CHAR INTEGER INT64 REAL STRING ARRAY OF RECORD
%token ADD SUB MUL REAL_DIV DIV MOD LT LE GT GE EQ NE CARET AT
%token AND NOT OR XOR SHL SHR
%token INTEGER_LITERAL REAL_LITERAL STRING_LITERAL BOOLEAN_LITERAL CHAR_LITERAL
@@ -63,7 +63,7 @@ YY_DECL;
%type <bool> BOOLEAN_LITERAL TO
%type <char> CHAR_LITERAL
-%type <int> INTEGER_LITERAL
+%type <long long> INTEGER_LITERAL
%type <float> REAL_LITERAL
%type <std::vector<char>> STRING_LITERAL
%type <std::shared_ptr<pcc::ExprNode>> literal lvalue rvalue standalone
@@ -165,6 +165,7 @@ type
| BOOLEAN {$$=std::make_shared<TrivialTypeIdentifier>(ctx, ctx->GetTypeManager()->GetBuiltinType(pcc::BuiltinType::BOOLEAN));}
| CHAR {$$=std::make_shared<TrivialTypeIdentifier>(ctx, ctx->GetTypeManager()->GetBuiltinType(pcc::BuiltinType::CHAR));}
| INTEGER {$$=std::make_shared<TrivialTypeIdentifier>(ctx, ctx->GetTypeManager()->GetBuiltinType(pcc::BuiltinType::INTEGER));}
+ | INT64 {$$=std::make_shared<TrivialTypeIdentifier>(ctx, ctx->GetTypeManager()->GetBuiltinType(pcc::BuiltinType::INT64));}
| REAL {$$=std::make_shared<TrivialTypeIdentifier>(ctx, ctx->GetTypeManager()->GetBuiltinType(pcc::BuiltinType::REAL));}
| STRING {$$=std::make_shared<TrivialTypeIdentifier>(ctx, ctx->GetTypeManager()->GetBuiltinType(pcc::BuiltinType::STRING));}
| CARET type {$$=std::make_shared<PointerTypeIdentifier>(ctx, $2);}
@@ -302,7 +303,7 @@ arguments
literal
: BOOLEAN_LITERAL {$$=std::make_shared<pcc::BooleanLiteralNode>(ctx, ctx->GetTypeManager()->GetBuiltinType(BuiltinType::BOOLEAN), $1);}
| CHAR_LITERAL {$$=std::make_shared<pcc::CharLiteralNode>(ctx, ctx->GetTypeManager()->GetBuiltinType(BuiltinType::CHAR), $1);}
- | INTEGER_LITERAL {$$=std::make_shared<pcc::IntegerLiteralNode>(ctx, ctx->GetTypeManager()->GetBuiltinType(BuiltinType::INTEGER), $1);}
+ | INTEGER_LITERAL {$$=std::make_shared<pcc::IntegerLiteralNode>(ctx, ctx->GetTypeManager()->GetBuiltinType(BuiltinType::INT64), $1);}
| REAL_LITERAL {$$=std::make_shared<pcc::RealLiteralNode>(ctx, ctx->GetTypeManager()->GetBuiltinType(BuiltinType::REAL), $1);}
| STRING_LITERAL {$$=std::make_shared<pcc::StringLiteralNode>(ctx, ctx->GetTypeManager()->GetBuiltinType(BuiltinType::STRING), $1);}
;
diff --git a/Type.cc b/Type.cc
index 6167175..69196b9 100644
--- a/Type.cc
+++ b/Type.cc
@@ -254,6 +254,30 @@ Value IntegerType::CreateUnaryOperation(UnaryOperator op, Value v,
return (this->*operations[ToUnderlying(op)])(v, context);
}
+Int64Type::Int64Type()
+ : IntegerBaseType("int64", 64, llvm::Type::getInt64Ty(GlobalLLVMContext)) {}
+
+Value Int64Type::CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context) {
+ static Value (pcc::Int64Type::*operations[ToUnderlying(
+ BinaryOperator::BINARYOP_NUMBER)])(Value, Value, Context*) = {
+ &Int64Type::CreateAdd, &Int64Type::CreateSub, &Int64Type::CreateMul,
+ &Int64Type::CreateDiv, &Int64Type::CreateMod, &Int64Type::CreateLt,
+ &Int64Type::CreateLe, &Int64Type::CreateGt, &Int64Type::CreateGe,
+ &Int64Type::CreateEq, &Int64Type::CreateNe, &Int64Type::CreateAnd,
+ &Int64Type::CreateOr, &Int64Type::CreateXor, &Int64Type::CreateShl,
+ &Int64Type::CreateShr};
+ return (this->*operations[ToUnderlying(op)])(v0, v1, context);
+}
+
+Value Int64Type::CreateUnaryOperation(UnaryOperator op, Value v,
+ Context* context) {
+ static Value (pcc::Int64Type::*operations[ToUnderlying(
+ UnaryOperator::UNARYOP_NUMEBR)])(Value, Context*) = {
+ &Int64Type::CreatePos, &Int64Type::CreateNeg, &Int64Type::CreateNot};
+ return (this->*operations[ToUnderlying(op)])(v, context);
+}
+
RealType::RealType()
: Type("real", llvm::Type::getFloatTy(GlobalLLVMContext)) {}
diff --git a/Type.hh b/Type.hh
index e16b52f..b3779d4 100644
--- a/Type.hh
+++ b/Type.hh
@@ -141,6 +141,15 @@ class IntegerType : public IntegerBaseType {
Context* context) override;
};
+class Int64Type : public IntegerBaseType {
+ public:
+ Int64Type();
+ virtual Value CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context) override;
+ virtual Value CreateUnaryOperation(UnaryOperator op, Value v,
+ Context* context) override;
+};
+
class RealType : public Type {
public:
RealType();
diff --git a/TypeManager.cc b/TypeManager.cc
index 7402875..0cfbe75 100644
--- a/TypeManager.cc
+++ b/TypeManager.cc
@@ -5,11 +5,13 @@
namespace pcc {
TypeManager::TypeManager()
- : builtins_{std::make_shared<VoidType>(), std::make_shared<BooleanType>(),
- std::make_shared<CharType>(), std::make_shared<IntegerType>(),
- std::make_shared<RealType>()} {
- PointerDifferenceType_ = GetBuiltinType(BuiltinType::INTEGER);
- PointerIndexType_ = GetBuiltinType(BuiltinType::INTEGER);
+ : builtins_{std::make_shared<VoidType>(), std::make_shared<BooleanType>(),
+ std::make_shared<CharType>(), std::make_shared<IntegerType>(),
+ std::make_shared<Int64Type>(), std::make_shared<RealType>()} {
+ PointerIndexType_ = GetBuiltinType(BuiltinType::INT64);
+ PointerDifferenceType_ = GetBuiltinType(BuiltinType::INT64);
+ // llvm seems doesn't support GEP with i64 index type on records
+ RecordMemberIndexType_ = GetBuiltinType(BuiltinType::INTEGER);
builtins_.push_back(
GetPointerType(GetBuiltinType(BuiltinType::CHAR), "string"));
// llvm doesn't have void* type, we use char* instead
@@ -272,4 +274,8 @@ std::shared_ptr<Type> TypeManager::GetPointerDifferenceType() {
return PointerDifferenceType_;
}
+std::shared_ptr<Type> TypeManager::GetRecordMemberIndexType() {
+ return RecordMemberIndexType_;
+}
+
} // namespace pcc
diff --git a/TypeManager.hh b/TypeManager.hh
index 9f778a8..ce54dcb 100644
--- a/TypeManager.hh
+++ b/TypeManager.hh
@@ -16,6 +16,7 @@ enum class BuiltinType {
BOOLEAN,
CHAR,
INTEGER,
+ INT64,
REAL,
STRING,
BUILTIN_NUMBER
@@ -27,6 +28,7 @@ class TypeManager {
std::shared_ptr<Type> GetBuiltinType(BuiltinType type);
std::shared_ptr<Type> GetPointerIndexType();
std::shared_ptr<Type> GetPointerDifferenceType();
+ std::shared_ptr<Type> GetRecordMemberIndexType();
// if call this function twice with the same ElementType, it will return the
// same shared_ptr to the Type.
@@ -73,6 +75,7 @@ class TypeManager {
// 64-bit type, in order to make pointers behave correctly
std::shared_ptr<Type> PointerDifferenceType_;
std::shared_ptr<Type> PointerIndexType_;
+ std::shared_ptr<Type> RecordMemberIndexType_;
};
} // namespace pcc
diff --git a/node/ExprNode.cc b/node/ExprNode.cc
index e75eda5..c0a3f41 100644
--- a/node/ExprNode.cc
+++ b/node/ExprNode.cc
@@ -126,10 +126,11 @@ Value ArrayAccessNode::CodeGen() {
Value indices[2] = {llvm::ConstantInt::get(
manager->GetPointerIndexType()->GetLLVMType(), 0)};
if (array->GetIsZeroStarted() == false) {
- Value ConvertedRight =
+ Value CastedRight =
manager->CreateCast(IndexType, RightType, right, context_);
auto AdjustedRight = IndexType->CreateBinaryOperation(
- BinaryOperator::SUB, right, array->GetIndexStart(), context_);
+ BinaryOperator::SUB, CastedRight, array->GetIndexStart(),
+ context_);
indices[1] = AdjustedRight;
} else {
indices[1] = right;
@@ -201,7 +202,8 @@ Value MemberAccessNode::CodeGen() {
int MemberIndex;
std::shared_ptr<Type> MemberType;
std::tie(MemberIndex, MemberType) = LeftInner->GetMember(rhs_);
- llvm::Type* IndexLLLVMType = manager->GetPointerIndexType()->GetLLVMType();
+ llvm::Type* IndexLLLVMType =
+ manager->GetRecordMemberIndexType()->GetLLVMType();
Value indices[2] = {llvm::ConstantInt::get(IndexLLLVMType, 0),
llvm::ConstantInt::get(IndexLLLVMType, MemberIndex)};
type_ = manager->GetPointerType(MemberType);
diff --git a/node/LiteralNode.hh b/node/LiteralNode.hh
index 06f2989..f93c171 100644
--- a/node/LiteralNode.hh
+++ b/node/LiteralNode.hh
@@ -28,7 +28,7 @@ LiteralNode<T>::LiteralNode(Context* context, std::shared_ptr<Type> type,
using BooleanLiteralNode = LiteralNode<bool>;
using CharLiteralNode = LiteralNode<char>;
-using IntegerLiteralNode = LiteralNode<int>;
+using IntegerLiteralNode = LiteralNode<long long>;
using RealLiteralNode = LiteralNode<float>;
class StringLiteralNode : public ExprNode {
diff --git a/t/extern.pas b/t/extern.pas
index 89a3c78..92c0481 100644
--- a/t/extern.pas
+++ b/t/extern.pas
@@ -10,7 +10,7 @@ var
i:integer;
begin
Pascal_puts('Hello, World!');
- Pascal_printf('Variadic Function Test: %d, %s, %x\n', 1, 'yes', 0x12345678);
+ Pascal_printf('Variadic Function Test: %d, %s, %llx\n', 1, 'yes', 0x123456789abcd);
for i:=0 to 10 do
begin
if i=3 then continue;
diff --git a/t/sha1.pas b/t/sha1.pas
index 35c9341..523593b 100644
--- a/t/sha1.pas
+++ b/t/sha1.pas
@@ -3,7 +3,7 @@ program sha1;
type
sha1_ctx = record
h:array [0..4] of integer;
- bytes:integer;
+ bytes:int64;
buf:array [0..63] of char
end;
@@ -119,8 +119,8 @@ end;
function sha1_final(md:^char; ctx:^sha1_ctx):void;
var
- used, free:integer;
- bits, i:integer;
+ used, free, i:integer;
+ bits:int64;
begin
used := ctx^.bytes and 0x3f;
ctx^.buf[used] := 0x80;
@@ -134,9 +134,7 @@ begin
end;
memset(@ctx^.buf[used], 0, free-8);
bits := ctx^.bytes shl 3;
- for i := 0 to 3 do
- ctx^.buf[56+i] := 0;
- for i := 4 to 7 do
+ for i := 0 to 7 do
ctx^.buf[i+56] := bits shr (8*(7-i));
sha1_body(ctx, @ctx^.buf, 64);
for i := 0 to 19 do