diff options
| author | Nagi5Yeq <wu@x-nagi.com> | 2020-06-01 21:34:58 +0800 |
|---|---|---|
| committer | Nagi5Yeq <wu@x-nagi.com> | 2020-06-01 21:34:58 +0800 |
| commit | cd1466f30c146e12faa0db7e1b53b508bf2274c6 (patch) | |
| tree | d938d02d17bbf4949b0dc1d21dee861afe171bdc | |
| parent | f90115fba35887aea8d4064b57f4909cd6937134 (diff) | |
64 bit support
| -rw-r--r-- | Lexer.l | 3 | ||||
| -rw-r--r-- | Parser.y | 7 | ||||
| -rw-r--r-- | Type.cc | 24 | ||||
| -rw-r--r-- | Type.hh | 9 | ||||
| -rw-r--r-- | TypeManager.cc | 16 | ||||
| -rw-r--r-- | TypeManager.hh | 3 | ||||
| -rw-r--r-- | node/ExprNode.cc | 8 | ||||
| -rw-r--r-- | node/LiteralNode.hh | 2 | ||||
| -rw-r--r-- | t/extern.pas | 2 | ||||
| -rw-r--r-- | t/sha1.pas | 10 |
10 files changed, 64 insertions, 20 deletions
@@ -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); } @@ -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);} ; @@ -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)) {} @@ -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; @@ -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 |
