mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 21:29:20 +00:00
Add support for global types and type resolution. Fix several minor
formatting and spacing bugs. This is sufficient for llvm-upgrade to correctly upgrade all of llvm/test. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32114 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
97af751deb
commit
a50d5962ed
@ -42,7 +42,7 @@ int yyerror(const char *ErrorMsg) ;
|
|||||||
enum Types {
|
enum Types {
|
||||||
BoolTy, SByteTy, UByteTy, ShortTy, UShortTy, IntTy, UIntTy, LongTy, ULongTy,
|
BoolTy, SByteTy, UByteTy, ShortTy, UShortTy, IntTy, UIntTy, LongTy, ULongTy,
|
||||||
FloatTy, DoubleTy, PointerTy, PackedTy, ArrayTy, StructTy, OpaqueTy, VoidTy,
|
FloatTy, DoubleTy, PointerTy, PackedTy, ArrayTy, StructTy, OpaqueTy, VoidTy,
|
||||||
LabelTy, FunctionTy
|
LabelTy, FunctionTy, UnresolvedTy, NumericTy
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This type is used to keep track of the signedness of the obsolete
|
/// This type is used to keep track of the signedness of the obsolete
|
||||||
@ -56,28 +56,28 @@ struct TypeInfo {
|
|||||||
std::string* newTy;
|
std::string* newTy;
|
||||||
Types oldTy;
|
Types oldTy;
|
||||||
|
|
||||||
void destroy() { delete newTy; }
|
void destroy() const { delete newTy; }
|
||||||
|
|
||||||
bool isSigned() {
|
bool isSigned() const {
|
||||||
return oldTy == SByteTy || oldTy == ShortTy ||
|
return oldTy == SByteTy || oldTy == ShortTy ||
|
||||||
oldTy == IntTy || oldTy == LongTy;
|
oldTy == IntTy || oldTy == LongTy;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isUnsigned() {
|
bool isUnsigned() const {
|
||||||
return oldTy == UByteTy || oldTy == UShortTy ||
|
return oldTy == UByteTy || oldTy == UShortTy ||
|
||||||
oldTy == UIntTy || oldTy == ULongTy;
|
oldTy == UIntTy || oldTy == ULongTy;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSignless() { return !isSigned() && !isUnsigned(); }
|
bool isSignless() const { return !isSigned() && !isUnsigned(); }
|
||||||
bool isInteger() { return isSigned() || isUnsigned(); }
|
bool isInteger() const { return isSigned() || isUnsigned(); }
|
||||||
bool isIntegral() { return oldTy == BoolTy || isInteger(); }
|
bool isIntegral() const { return oldTy == BoolTy || isInteger(); }
|
||||||
bool isFloatingPoint() { return oldTy == DoubleTy || oldTy == FloatTy; }
|
bool isFloatingPoint() const { return oldTy == DoubleTy || oldTy == FloatTy; }
|
||||||
bool isPacked() { return oldTy == PackedTy; }
|
bool isPacked() const { return oldTy == PackedTy; }
|
||||||
bool isPointer() { return oldTy == PointerTy; }
|
bool isPointer() const { return oldTy == PointerTy; }
|
||||||
bool isOther() { return !isPacked() && !isPointer() && !isFloatingPoint()
|
bool isOther() const {
|
||||||
&& !isIntegral(); }
|
return !isPacked() && !isPointer() && !isFloatingPoint() && !isIntegral(); }
|
||||||
|
|
||||||
unsigned getBitWidth() {
|
unsigned getBitWidth() const {
|
||||||
switch (oldTy) {
|
switch (oldTy) {
|
||||||
case LabelTy:
|
case LabelTy:
|
||||||
case VoidTy : return 0;
|
case VoidTy : return 0;
|
||||||
|
@ -1471,7 +1471,7 @@ YY_RULE_SETUP
|
|||||||
case 58:
|
case 58:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 160 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeLexer.l"
|
#line 160 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeLexer.l"
|
||||||
{ RET_TY(OPAQUE,OpaqueTy,"opaque",false); }
|
{ RET_TOK(OPAQUE); }
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 59:
|
case 59:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
|
@ -1471,7 +1471,7 @@ YY_RULE_SETUP
|
|||||||
case 58:
|
case 58:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 160 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeLexer.l"
|
#line 160 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeLexer.l"
|
||||||
{ RET_TY(OPAQUE,OpaqueTy,"opaque",false); }
|
{ RET_TOK(OPAQUE); }
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 59:
|
case 59:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
|
@ -157,7 +157,7 @@ ulong { RET_TY(ULONG,ULongTy,"ulong",false); }
|
|||||||
float { RET_TY(FLOAT,FloatTy,"float",false); }
|
float { RET_TY(FLOAT,FloatTy,"float",false); }
|
||||||
double { RET_TY(DOUBLE,DoubleTy,"double",false); }
|
double { RET_TY(DOUBLE,DoubleTy,"double",false); }
|
||||||
label { RET_TY(LABEL,LabelTy,"label",false); }
|
label { RET_TY(LABEL,LabelTy,"label",false); }
|
||||||
opaque { RET_TY(OPAQUE,OpaqueTy,"opaque",false); }
|
opaque { RET_TOK(OPAQUE); }
|
||||||
type { RET_TOK(TYPE); }
|
type { RET_TOK(TYPE); }
|
||||||
|
|
||||||
add { RET_TOK( ADD); }
|
add { RET_TOK( ADD); }
|
||||||
|
@ -157,7 +157,7 @@ ulong { RET_TY(ULONG,ULongTy,"ulong",false); }
|
|||||||
float { RET_TY(FLOAT,FloatTy,"float",false); }
|
float { RET_TY(FLOAT,FloatTy,"float",false); }
|
||||||
double { RET_TY(DOUBLE,DoubleTy,"double",false); }
|
double { RET_TY(DOUBLE,DoubleTy,"double",false); }
|
||||||
label { RET_TY(LABEL,LabelTy,"label",false); }
|
label { RET_TY(LABEL,LabelTy,"label",false); }
|
||||||
opaque { RET_TY(OPAQUE,OpaqueTy,"opaque",false); }
|
opaque { RET_TOK(OPAQUE); }
|
||||||
type { RET_TOK(TYPE); }
|
type { RET_TOK(TYPE); }
|
||||||
|
|
||||||
add { RET_TOK( ADD); }
|
add { RET_TOK( ADD); }
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -281,7 +281,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
|
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
|
||||||
#line 154 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
|
#line 201 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
|
||||||
typedef union YYSTYPE {
|
typedef union YYSTYPE {
|
||||||
std::string* String;
|
std::string* String;
|
||||||
TypeInfo Type;
|
TypeInfo Type;
|
||||||
|
@ -281,7 +281,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
|
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
|
||||||
#line 154 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
|
#line 201 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
|
||||||
typedef union YYSTYPE {
|
typedef union YYSTYPE {
|
||||||
std::string* String;
|
std::string* String;
|
||||||
TypeInfo Type;
|
TypeInfo Type;
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
#include "ParserInternals.h"
|
#include "ParserInternals.h"
|
||||||
#include <llvm/ADT/StringExtras.h>
|
#include <llvm/ADT/StringExtras.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <list>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@ -32,6 +33,11 @@ static std::ostream *O = 0;
|
|||||||
std::istream* LexInput = 0;
|
std::istream* LexInput = 0;
|
||||||
unsigned SizeOfPointer = 32;
|
unsigned SizeOfPointer = 32;
|
||||||
|
|
||||||
|
typedef std::vector<TypeInfo> TypeVector;
|
||||||
|
static TypeVector EnumeratedTypes;
|
||||||
|
typedef std::map<std::string,TypeInfo> TypeMap;
|
||||||
|
static TypeMap NamedTypes;
|
||||||
|
|
||||||
void UpgradeAssembly(const std::string &infile, std::istream& in,
|
void UpgradeAssembly(const std::string &infile, std::istream& in,
|
||||||
std::ostream &out, bool debug)
|
std::ostream &out, bool debug)
|
||||||
{
|
{
|
||||||
@ -47,26 +53,32 @@ void UpgradeAssembly(const std::string &infile, std::istream& in,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getCastUpgrade(std::string& Source, TypeInfo& SrcTy,
|
static void ResolveType(TypeInfo& Ty) {
|
||||||
TypeInfo&DstTy, bool isConst = false)
|
if (Ty.oldTy == UnresolvedTy) {
|
||||||
{
|
TypeMap::iterator I = NamedTypes.find(*Ty.newTy);
|
||||||
std::string Result;
|
if (I != NamedTypes.end())
|
||||||
if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
|
Ty.oldTy = I->second.oldTy;
|
||||||
if (isConst)
|
|
||||||
Source = "ulong fptoui(" + Source + " to ulong)";
|
|
||||||
else {
|
else {
|
||||||
Result = "%cast_upgrade = fptoui " + Source + " to ulong";
|
std::string msg("Can't resolve type: ");
|
||||||
Source = "ulong %cast_upgrade";
|
msg += *Ty.newTy;
|
||||||
|
yyerror(msg.c_str());
|
||||||
}
|
}
|
||||||
SrcTy.destroy();
|
} else if (Ty.oldTy == NumericTy) {
|
||||||
SrcTy.newTy = new std::string("ulong");
|
unsigned ref = atoi(&((Ty.newTy->c_str())[1])); // Skip the '\\'
|
||||||
SrcTy.oldTy = ULongTy;
|
if (ref < EnumeratedTypes.size()) {
|
||||||
|
Ty.oldTy = EnumeratedTypes[ref].oldTy;
|
||||||
|
} else {
|
||||||
|
std::string msg("Can't resolve type: ");
|
||||||
|
msg += *Ty.newTy;
|
||||||
|
yyerror(msg.c_str());
|
||||||
}
|
}
|
||||||
return Result;
|
}
|
||||||
|
// otherwise its already resolved.
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* getCastOpcode(std::string& Source, TypeInfo& SrcTy,
|
static const char* getCastOpcode(
|
||||||
TypeInfo&DstTy) {
|
std::string& Source, const TypeInfo& SrcTy, const TypeInfo& DstTy)
|
||||||
|
{
|
||||||
unsigned SrcBits = SrcTy.getBitWidth();
|
unsigned SrcBits = SrcTy.getBitWidth();
|
||||||
unsigned DstBits = DstTy.getBitWidth();
|
unsigned DstBits = DstTy.getBitWidth();
|
||||||
const char* opcode = "bitcast";
|
const char* opcode = "bitcast";
|
||||||
@ -133,13 +145,8 @@ const char* getCastOpcode(std::string& Source, TypeInfo& SrcTy,
|
|||||||
opcode = "bitcast"; // ptr -> ptr
|
opcode = "bitcast"; // ptr -> ptr
|
||||||
} else if (SrcTy.isIntegral()) {
|
} else if (SrcTy.isIntegral()) {
|
||||||
opcode = "inttoptr"; // int -> ptr
|
opcode = "inttoptr"; // int -> ptr
|
||||||
} else if (SrcTy.isFloatingPoint()) { // float/double -> ptr
|
|
||||||
// Cast to int first
|
|
||||||
*O << " %upgrade_cast = fptoui " << Source << " to ulong\n";
|
|
||||||
opcode = "inttoptr";
|
|
||||||
Source = "ulong %upgrade_cast";
|
|
||||||
} else {
|
} else {
|
||||||
assert(!"Casting pointer to other than pointer or int");
|
assert(!"Casting invalid type to pointer");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(!"Casting to type that is not first-class");
|
assert(!"Casting to type that is not first-class");
|
||||||
@ -147,6 +154,46 @@ const char* getCastOpcode(std::string& Source, TypeInfo& SrcTy,
|
|||||||
return opcode;
|
return opcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string getCastUpgrade(
|
||||||
|
const std::string& Src, TypeInfo& SrcTy, TypeInfo& DstTy, bool isConst)
|
||||||
|
{
|
||||||
|
std::string Result;
|
||||||
|
std::string Source = Src;
|
||||||
|
if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
|
||||||
|
// fp -> ptr cast is no longer supported but we must upgrade this
|
||||||
|
// by doing a double cast: fp -> int -> ptr
|
||||||
|
if (isConst)
|
||||||
|
Source = "ulong fptoui(" + Source + " to ulong)";
|
||||||
|
else {
|
||||||
|
*O << " %cast_upgrade = fptoui " + Source + " to ulong\n";
|
||||||
|
Source = "ulong %cast_upgrade";
|
||||||
|
}
|
||||||
|
// Update the SrcTy for the getCastOpcode call below
|
||||||
|
SrcTy.destroy();
|
||||||
|
SrcTy.newTy = new std::string("ulong");
|
||||||
|
SrcTy.oldTy = ULongTy;
|
||||||
|
} else if (DstTy.oldTy == BoolTy) {
|
||||||
|
// cast ptr %x to bool was previously defined as setne ptr %x, null
|
||||||
|
// The ptrtoint semantic is to truncate, not compare so we must retain
|
||||||
|
// the original intent by replace the cast with a setne
|
||||||
|
const char* comparator = SrcTy.isPointer() ? ", null" :
|
||||||
|
(SrcTy.isFloatingPoint() ? ", 0.0" : ", 0");
|
||||||
|
if (isConst)
|
||||||
|
Result = "setne (" + Source + comparator + ")";
|
||||||
|
else
|
||||||
|
Result = "setne " + Source + comparator;
|
||||||
|
return Result; // skip cast processing below
|
||||||
|
}
|
||||||
|
ResolveType(SrcTy);
|
||||||
|
ResolveType(DstTy);
|
||||||
|
std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
|
||||||
|
if (isConst)
|
||||||
|
Result += Opcode + "( " + Source + " to " + *DstTy.newTy + ")";
|
||||||
|
else
|
||||||
|
Result += Opcode + " " + Source + " to " + *DstTy.newTy;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%file-prefix="UpgradeParser"
|
%file-prefix="UpgradeParser"
|
||||||
@ -159,8 +206,8 @@ const char* getCastOpcode(std::string& Source, TypeInfo& SrcTy,
|
|||||||
}
|
}
|
||||||
|
|
||||||
%token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
|
%token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
|
||||||
%token <Type> FLOAT DOUBLE LABEL OPAQUE
|
%token <Type> FLOAT DOUBLE LABEL
|
||||||
%token <String> ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
|
%token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
|
||||||
%token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
|
%token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
|
||||||
%token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
|
%token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
|
||||||
%token <String> IMPLEMENTATION BEGINTOK ENDTOK
|
%token <String> IMPLEMENTATION BEGINTOK ENDTOK
|
||||||
@ -232,7 +279,6 @@ FPType : FLOAT | DOUBLE;
|
|||||||
|
|
||||||
// OptAssign - Value producing statements have an optional assignment component
|
// OptAssign - Value producing statements have an optional assignment component
|
||||||
OptAssign : Name '=' {
|
OptAssign : Name '=' {
|
||||||
*$1 += " = ";
|
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| /*empty*/ {
|
| /*empty*/ {
|
||||||
@ -312,17 +358,24 @@ Types : UpRTypes ;
|
|||||||
//
|
//
|
||||||
PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
|
PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
|
||||||
PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
|
PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
|
||||||
UpRTypes : OPAQUE | PrimType
|
UpRTypes
|
||||||
|
: OPAQUE {
|
||||||
|
$$.newTy = $1;
|
||||||
|
$$.oldTy = OpaqueTy;
|
||||||
|
}
|
||||||
| SymbolicValueRef {
|
| SymbolicValueRef {
|
||||||
$$.newTy = $1; $$.oldTy = OpaqueTy;
|
$$.newTy = $1;
|
||||||
};
|
$$.oldTy = UnresolvedTy;
|
||||||
|
}
|
||||||
|
| PrimType
|
||||||
|
;
|
||||||
|
|
||||||
// Include derived types in the Types production.
|
// Include derived types in the Types production.
|
||||||
//
|
//
|
||||||
UpRTypes : '\\' EUINT64VAL { // Type UpReference
|
UpRTypes : '\\' EUINT64VAL { // Type UpReference
|
||||||
$2->insert(0, "\\");
|
$2->insert(0, "\\");
|
||||||
$$.newTy = $2;
|
$$.newTy = $2;
|
||||||
$$.oldTy = OpaqueTy;
|
$$.oldTy = NumericTy;
|
||||||
}
|
}
|
||||||
| UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
|
| UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
|
||||||
*$1.newTy += "( " + *$3 + " )";
|
*$1.newTy += "( " + *$3 + " )";
|
||||||
@ -491,17 +544,17 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
|
|||||||
|
|
||||||
|
|
||||||
ConstExpr: CastOps '(' ConstVal TO Types ')' {
|
ConstExpr: CastOps '(' ConstVal TO Types ')' {
|
||||||
// We must infer the cast opcode from the types of the operands.
|
|
||||||
const char *opcode = $1->c_str();
|
|
||||||
std::string source = *$3.cnst;
|
std::string source = *$3.cnst;
|
||||||
|
TypeInfo DstTy = $5;
|
||||||
|
ResolveType(DstTy);
|
||||||
if (*$1 == "cast") {
|
if (*$1 == "cast") {
|
||||||
std::string upgrade = getCastUpgrade(source, $3.type, $5, true);
|
// Call getCastUpgrade to upgrade the old cast
|
||||||
opcode = getCastOpcode(source, $3.type, $5);
|
$$ = new std::string(getCastUpgrade(source, $3.type, $5, true));
|
||||||
if (!upgrade.empty())
|
} else {
|
||||||
source = upgrade;
|
// Nothing to upgrade, just create the cast constant expr
|
||||||
|
$$ = new std::string(*$1);
|
||||||
|
*$$ += "( " + source + " to " + *$5.newTy + ")";
|
||||||
}
|
}
|
||||||
$$ = new std::string(opcode);
|
|
||||||
*$$ += "( " + source + " " + *$4 + " " + *$5.newTy + ")";
|
|
||||||
delete $1; $3.destroy(); delete $4; $5.destroy();
|
delete $1; $3.destroy(); delete $4; $5.destroy();
|
||||||
}
|
}
|
||||||
| GETELEMENTPTR '(' ConstVal IndexList ')' {
|
| GETELEMENTPTR '(' ConstVal IndexList ')' {
|
||||||
@ -599,12 +652,18 @@ DefinitionList : DefinitionList Function {
|
|||||||
*O << "implementation\n";
|
*O << "implementation\n";
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
| ConstPool;
|
| ConstPool { $$ = 0; }
|
||||||
|
|
||||||
// ConstPool - Constants with optional names assigned to them.
|
// ConstPool - Constants with optional names assigned to them.
|
||||||
ConstPool : ConstPool OptAssign TYPE TypesV {
|
ConstPool : ConstPool OptAssign TYPE TypesV {
|
||||||
*O << *$2 << " " << *$3 << " " << *$4.newTy << "\n";
|
EnumeratedTypes.push_back($4);
|
||||||
// delete $2; delete $3; $4.destroy();
|
if (!$2->empty()) {
|
||||||
|
NamedTypes[*$2].newTy = new std::string(*$4.newTy);
|
||||||
|
NamedTypes[*$2].oldTy = $4.oldTy;
|
||||||
|
*O << *$2 << " = ";
|
||||||
|
}
|
||||||
|
*O << "type " << *$4.newTy << "\n";
|
||||||
|
delete $2; delete $3; $4.destroy();
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
| ConstPool FunctionProto { // Function prototypes can be in const pool
|
| ConstPool FunctionProto { // Function prototypes can be in const pool
|
||||||
@ -618,26 +677,30 @@ ConstPool : ConstPool OptAssign TYPE TypesV {
|
|||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
| ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
|
| ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
|
||||||
*O << *$2 << " " << *$3 << " " << *$4 << " " << *$5.cnst << " "
|
if (!$2->empty())
|
||||||
<< *$6 << "\n";
|
*O << *$2 << " = ";
|
||||||
|
*O << *$3 << " " << *$4 << " " << *$5.cnst << " " << *$6 << "\n";
|
||||||
delete $2; delete $3; delete $4; $5.destroy(); delete $6;
|
delete $2; delete $3; delete $4; $5.destroy(); delete $6;
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
| ConstPool OptAssign EXTERNAL GlobalType Types GlobalVarAttributes {
|
| ConstPool OptAssign EXTERNAL GlobalType Types GlobalVarAttributes {
|
||||||
*O << *$2 << " " << *$3 << " " << *$4 << " " << *$5.newTy
|
if (!$2->empty())
|
||||||
<< " " << *$6 << "\n";
|
*O << *$2 << " = ";
|
||||||
|
*O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
|
||||||
delete $2; delete $3; delete $4; $5.destroy(); delete $6;
|
delete $2; delete $3; delete $4; $5.destroy(); delete $6;
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
| ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
|
| ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
|
||||||
*O << *$2 << " " << *$3 << " " << *$4 << " " << *$5.newTy
|
if (!$2->empty())
|
||||||
<< " " << *$6 << "\n";
|
*O << *$2 << " = ";
|
||||||
|
*O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
|
||||||
delete $2; delete $3; delete $4; $5.destroy(); delete $6;
|
delete $2; delete $3; delete $4; $5.destroy(); delete $6;
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
| ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
|
| ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
|
||||||
*O << *$2 << " " << *$3 << " " << *$4 << " " << *$5.newTy
|
if (!$2->empty())
|
||||||
<< " " << *$6 << "\n";
|
*O << *$2 << " = ";
|
||||||
|
*O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
|
||||||
delete $2; delete $3; delete $4; $5.destroy(); delete $6;
|
delete $2; delete $3; delete $4; $5.destroy(); delete $6;
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
@ -907,7 +970,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
|
|||||||
TO LABEL ValueRef UNWIND LABEL ValueRef {
|
TO LABEL ValueRef UNWIND LABEL ValueRef {
|
||||||
*O << " ";
|
*O << " ";
|
||||||
if (!$1->empty())
|
if (!$1->empty())
|
||||||
*O << *$1;
|
*O << *$1 << " = ";
|
||||||
*O << *$2 << " " << *$3 << " " << *$4.newTy << " " << *$5 << " ("
|
*O << *$2 << " " << *$3 << " " << *$4.newTy << " " << *$5 << " ("
|
||||||
<< *$7 << ") " << *$9 << " " << *$10.newTy << " " << *$11 << " "
|
<< *$7 << ") " << *$9 << " " << *$10.newTy << " " << *$11 << " "
|
||||||
<< *$12 << " " << *$13.newTy << " " << *$14 << "\n";
|
<< *$12 << " " << *$13.newTy << " " << *$14 << "\n";
|
||||||
@ -941,6 +1004,8 @@ JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
|
|||||||
|
|
||||||
Inst
|
Inst
|
||||||
: OptAssign InstVal {
|
: OptAssign InstVal {
|
||||||
|
if (!$1->empty())
|
||||||
|
*$1 += " = ";
|
||||||
*$1 += *$2;
|
*$1 += *$2;
|
||||||
delete $2;
|
delete $2;
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -1012,16 +1077,16 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
|||||||
delete $1; $2.destroy(); $4.destroy();
|
delete $1; $2.destroy(); $4.destroy();
|
||||||
}
|
}
|
||||||
| CastOps ResolvedVal TO Types {
|
| CastOps ResolvedVal TO Types {
|
||||||
const char *opcode = $1->c_str();
|
|
||||||
std::string source = *$2.val;
|
std::string source = *$2.val;
|
||||||
|
TypeInfo SrcTy = $2.type;
|
||||||
|
TypeInfo DstTy = $4;
|
||||||
|
ResolveType(DstTy);
|
||||||
|
$$ = new std::string();
|
||||||
if (*$1 == "cast") {
|
if (*$1 == "cast") {
|
||||||
std::string upgrade = getCastUpgrade(source, $2.type, $4, false);
|
*$$ += getCastUpgrade(source, SrcTy, DstTy, false);
|
||||||
if (!upgrade.empty())
|
} else {
|
||||||
*O << " " << upgrade << "\n";
|
*$$ += *$1 + " " + source + " to " + *DstTy.newTy;
|
||||||
opcode = getCastOpcode(source, $2.type, $4);
|
|
||||||
}
|
}
|
||||||
$$ = new std::string(opcode);
|
|
||||||
*$$ += " " + source + " " + *$3 + " " + *$4.newTy;
|
|
||||||
delete $1; $2.destroy();
|
delete $1; $2.destroy();
|
||||||
delete $3; $4.destroy();
|
delete $3; $4.destroy();
|
||||||
}
|
}
|
||||||
@ -1129,7 +1194,7 @@ MemoryInst : MALLOC Types OptCAlign {
|
|||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| GETELEMENTPTR Types ValueRef IndexList {
|
| GETELEMENTPTR Types ValueRef IndexList {
|
||||||
*$1 += *$2.newTy + " " + *$3 + " " + *$4;
|
*$1 += " " + *$2.newTy + " " + *$3 + " " + *$4;
|
||||||
$2.destroy(); delete $3; delete $4;
|
$2.destroy(); delete $3; delete $4;
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
};
|
};
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
#include "ParserInternals.h"
|
#include "ParserInternals.h"
|
||||||
#include <llvm/ADT/StringExtras.h>
|
#include <llvm/ADT/StringExtras.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <list>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@ -32,6 +33,11 @@ static std::ostream *O = 0;
|
|||||||
std::istream* LexInput = 0;
|
std::istream* LexInput = 0;
|
||||||
unsigned SizeOfPointer = 32;
|
unsigned SizeOfPointer = 32;
|
||||||
|
|
||||||
|
typedef std::vector<TypeInfo> TypeVector;
|
||||||
|
static TypeVector EnumeratedTypes;
|
||||||
|
typedef std::map<std::string,TypeInfo> TypeMap;
|
||||||
|
static TypeMap NamedTypes;
|
||||||
|
|
||||||
void UpgradeAssembly(const std::string &infile, std::istream& in,
|
void UpgradeAssembly(const std::string &infile, std::istream& in,
|
||||||
std::ostream &out, bool debug)
|
std::ostream &out, bool debug)
|
||||||
{
|
{
|
||||||
@ -47,26 +53,32 @@ void UpgradeAssembly(const std::string &infile, std::istream& in,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getCastUpgrade(std::string& Source, TypeInfo& SrcTy,
|
static void ResolveType(TypeInfo& Ty) {
|
||||||
TypeInfo&DstTy, bool isConst = false)
|
if (Ty.oldTy == UnresolvedTy) {
|
||||||
{
|
TypeMap::iterator I = NamedTypes.find(*Ty.newTy);
|
||||||
std::string Result;
|
if (I != NamedTypes.end())
|
||||||
if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
|
Ty.oldTy = I->second.oldTy;
|
||||||
if (isConst)
|
|
||||||
Source = "ulong fptoui(" + Source + " to ulong)";
|
|
||||||
else {
|
else {
|
||||||
Result = "%cast_upgrade = fptoui " + Source + " to ulong";
|
std::string msg("Can't resolve type: ");
|
||||||
Source = "ulong %cast_upgrade";
|
msg += *Ty.newTy;
|
||||||
|
yyerror(msg.c_str());
|
||||||
}
|
}
|
||||||
SrcTy.destroy();
|
} else if (Ty.oldTy == NumericTy) {
|
||||||
SrcTy.newTy = new std::string("ulong");
|
unsigned ref = atoi(&((Ty.newTy->c_str())[1])); // Skip the '\\'
|
||||||
SrcTy.oldTy = ULongTy;
|
if (ref < EnumeratedTypes.size()) {
|
||||||
|
Ty.oldTy = EnumeratedTypes[ref].oldTy;
|
||||||
|
} else {
|
||||||
|
std::string msg("Can't resolve type: ");
|
||||||
|
msg += *Ty.newTy;
|
||||||
|
yyerror(msg.c_str());
|
||||||
}
|
}
|
||||||
return Result;
|
}
|
||||||
|
// otherwise its already resolved.
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* getCastOpcode(std::string& Source, TypeInfo& SrcTy,
|
static const char* getCastOpcode(
|
||||||
TypeInfo&DstTy) {
|
std::string& Source, const TypeInfo& SrcTy, const TypeInfo& DstTy)
|
||||||
|
{
|
||||||
unsigned SrcBits = SrcTy.getBitWidth();
|
unsigned SrcBits = SrcTy.getBitWidth();
|
||||||
unsigned DstBits = DstTy.getBitWidth();
|
unsigned DstBits = DstTy.getBitWidth();
|
||||||
const char* opcode = "bitcast";
|
const char* opcode = "bitcast";
|
||||||
@ -133,13 +145,8 @@ const char* getCastOpcode(std::string& Source, TypeInfo& SrcTy,
|
|||||||
opcode = "bitcast"; // ptr -> ptr
|
opcode = "bitcast"; // ptr -> ptr
|
||||||
} else if (SrcTy.isIntegral()) {
|
} else if (SrcTy.isIntegral()) {
|
||||||
opcode = "inttoptr"; // int -> ptr
|
opcode = "inttoptr"; // int -> ptr
|
||||||
} else if (SrcTy.isFloatingPoint()) { // float/double -> ptr
|
|
||||||
// Cast to int first
|
|
||||||
*O << " %upgrade_cast = fptoui " << Source << " to ulong\n";
|
|
||||||
opcode = "inttoptr";
|
|
||||||
Source = "ulong %upgrade_cast";
|
|
||||||
} else {
|
} else {
|
||||||
assert(!"Casting pointer to other than pointer or int");
|
assert(!"Casting invalid type to pointer");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(!"Casting to type that is not first-class");
|
assert(!"Casting to type that is not first-class");
|
||||||
@ -147,6 +154,46 @@ const char* getCastOpcode(std::string& Source, TypeInfo& SrcTy,
|
|||||||
return opcode;
|
return opcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string getCastUpgrade(
|
||||||
|
const std::string& Src, TypeInfo& SrcTy, TypeInfo& DstTy, bool isConst)
|
||||||
|
{
|
||||||
|
std::string Result;
|
||||||
|
std::string Source = Src;
|
||||||
|
if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
|
||||||
|
// fp -> ptr cast is no longer supported but we must upgrade this
|
||||||
|
// by doing a double cast: fp -> int -> ptr
|
||||||
|
if (isConst)
|
||||||
|
Source = "ulong fptoui(" + Source + " to ulong)";
|
||||||
|
else {
|
||||||
|
*O << " %cast_upgrade = fptoui " + Source + " to ulong\n";
|
||||||
|
Source = "ulong %cast_upgrade";
|
||||||
|
}
|
||||||
|
// Update the SrcTy for the getCastOpcode call below
|
||||||
|
SrcTy.destroy();
|
||||||
|
SrcTy.newTy = new std::string("ulong");
|
||||||
|
SrcTy.oldTy = ULongTy;
|
||||||
|
} else if (DstTy.oldTy == BoolTy) {
|
||||||
|
// cast ptr %x to bool was previously defined as setne ptr %x, null
|
||||||
|
// The ptrtoint semantic is to truncate, not compare so we must retain
|
||||||
|
// the original intent by replace the cast with a setne
|
||||||
|
const char* comparator = SrcTy.isPointer() ? ", null" :
|
||||||
|
(SrcTy.isFloatingPoint() ? ", 0.0" : ", 0");
|
||||||
|
if (isConst)
|
||||||
|
Result = "setne (" + Source + comparator + ")";
|
||||||
|
else
|
||||||
|
Result = "setne " + Source + comparator;
|
||||||
|
return Result; // skip cast processing below
|
||||||
|
}
|
||||||
|
ResolveType(SrcTy);
|
||||||
|
ResolveType(DstTy);
|
||||||
|
std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
|
||||||
|
if (isConst)
|
||||||
|
Result += Opcode + "( " + Source + " to " + *DstTy.newTy + ")";
|
||||||
|
else
|
||||||
|
Result += Opcode + " " + Source + " to " + *DstTy.newTy;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%file-prefix="UpgradeParser"
|
%file-prefix="UpgradeParser"
|
||||||
@ -159,8 +206,8 @@ const char* getCastOpcode(std::string& Source, TypeInfo& SrcTy,
|
|||||||
}
|
}
|
||||||
|
|
||||||
%token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
|
%token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
|
||||||
%token <Type> FLOAT DOUBLE LABEL OPAQUE
|
%token <Type> FLOAT DOUBLE LABEL
|
||||||
%token <String> ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
|
%token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
|
||||||
%token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
|
%token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
|
||||||
%token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
|
%token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
|
||||||
%token <String> IMPLEMENTATION BEGINTOK ENDTOK
|
%token <String> IMPLEMENTATION BEGINTOK ENDTOK
|
||||||
@ -232,7 +279,6 @@ FPType : FLOAT | DOUBLE;
|
|||||||
|
|
||||||
// OptAssign - Value producing statements have an optional assignment component
|
// OptAssign - Value producing statements have an optional assignment component
|
||||||
OptAssign : Name '=' {
|
OptAssign : Name '=' {
|
||||||
*$1 += " = ";
|
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| /*empty*/ {
|
| /*empty*/ {
|
||||||
@ -312,17 +358,24 @@ Types : UpRTypes ;
|
|||||||
//
|
//
|
||||||
PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
|
PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
|
||||||
PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
|
PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
|
||||||
UpRTypes : OPAQUE | PrimType
|
UpRTypes
|
||||||
|
: OPAQUE {
|
||||||
|
$$.newTy = $1;
|
||||||
|
$$.oldTy = OpaqueTy;
|
||||||
|
}
|
||||||
| SymbolicValueRef {
|
| SymbolicValueRef {
|
||||||
$$.newTy = $1; $$.oldTy = OpaqueTy;
|
$$.newTy = $1;
|
||||||
};
|
$$.oldTy = UnresolvedTy;
|
||||||
|
}
|
||||||
|
| PrimType
|
||||||
|
;
|
||||||
|
|
||||||
// Include derived types in the Types production.
|
// Include derived types in the Types production.
|
||||||
//
|
//
|
||||||
UpRTypes : '\\' EUINT64VAL { // Type UpReference
|
UpRTypes : '\\' EUINT64VAL { // Type UpReference
|
||||||
$2->insert(0, "\\");
|
$2->insert(0, "\\");
|
||||||
$$.newTy = $2;
|
$$.newTy = $2;
|
||||||
$$.oldTy = OpaqueTy;
|
$$.oldTy = NumericTy;
|
||||||
}
|
}
|
||||||
| UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
|
| UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
|
||||||
*$1.newTy += "( " + *$3 + " )";
|
*$1.newTy += "( " + *$3 + " )";
|
||||||
@ -491,17 +544,17 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
|
|||||||
|
|
||||||
|
|
||||||
ConstExpr: CastOps '(' ConstVal TO Types ')' {
|
ConstExpr: CastOps '(' ConstVal TO Types ')' {
|
||||||
// We must infer the cast opcode from the types of the operands.
|
|
||||||
const char *opcode = $1->c_str();
|
|
||||||
std::string source = *$3.cnst;
|
std::string source = *$3.cnst;
|
||||||
|
TypeInfo DstTy = $5;
|
||||||
|
ResolveType(DstTy);
|
||||||
if (*$1 == "cast") {
|
if (*$1 == "cast") {
|
||||||
std::string upgrade = getCastUpgrade(source, $3.type, $5, true);
|
// Call getCastUpgrade to upgrade the old cast
|
||||||
opcode = getCastOpcode(source, $3.type, $5);
|
$$ = new std::string(getCastUpgrade(source, $3.type, $5, true));
|
||||||
if (!upgrade.empty())
|
} else {
|
||||||
source = upgrade;
|
// Nothing to upgrade, just create the cast constant expr
|
||||||
|
$$ = new std::string(*$1);
|
||||||
|
*$$ += "( " + source + " to " + *$5.newTy + ")";
|
||||||
}
|
}
|
||||||
$$ = new std::string(opcode);
|
|
||||||
*$$ += "( " + source + " " + *$4 + " " + *$5.newTy + ")";
|
|
||||||
delete $1; $3.destroy(); delete $4; $5.destroy();
|
delete $1; $3.destroy(); delete $4; $5.destroy();
|
||||||
}
|
}
|
||||||
| GETELEMENTPTR '(' ConstVal IndexList ')' {
|
| GETELEMENTPTR '(' ConstVal IndexList ')' {
|
||||||
@ -599,12 +652,18 @@ DefinitionList : DefinitionList Function {
|
|||||||
*O << "implementation\n";
|
*O << "implementation\n";
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
| ConstPool;
|
| ConstPool { $$ = 0; }
|
||||||
|
|
||||||
// ConstPool - Constants with optional names assigned to them.
|
// ConstPool - Constants with optional names assigned to them.
|
||||||
ConstPool : ConstPool OptAssign TYPE TypesV {
|
ConstPool : ConstPool OptAssign TYPE TypesV {
|
||||||
*O << *$2 << " " << *$3 << " " << *$4.newTy << "\n";
|
EnumeratedTypes.push_back($4);
|
||||||
// delete $2; delete $3; $4.destroy();
|
if (!$2->empty()) {
|
||||||
|
NamedTypes[*$2].newTy = new std::string(*$4.newTy);
|
||||||
|
NamedTypes[*$2].oldTy = $4.oldTy;
|
||||||
|
*O << *$2 << " = ";
|
||||||
|
}
|
||||||
|
*O << "type " << *$4.newTy << "\n";
|
||||||
|
delete $2; delete $3; $4.destroy();
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
| ConstPool FunctionProto { // Function prototypes can be in const pool
|
| ConstPool FunctionProto { // Function prototypes can be in const pool
|
||||||
@ -618,26 +677,30 @@ ConstPool : ConstPool OptAssign TYPE TypesV {
|
|||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
| ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
|
| ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
|
||||||
*O << *$2 << " " << *$3 << " " << *$4 << " " << *$5.cnst << " "
|
if (!$2->empty())
|
||||||
<< *$6 << "\n";
|
*O << *$2 << " = ";
|
||||||
|
*O << *$3 << " " << *$4 << " " << *$5.cnst << " " << *$6 << "\n";
|
||||||
delete $2; delete $3; delete $4; $5.destroy(); delete $6;
|
delete $2; delete $3; delete $4; $5.destroy(); delete $6;
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
| ConstPool OptAssign EXTERNAL GlobalType Types GlobalVarAttributes {
|
| ConstPool OptAssign EXTERNAL GlobalType Types GlobalVarAttributes {
|
||||||
*O << *$2 << " " << *$3 << " " << *$4 << " " << *$5.newTy
|
if (!$2->empty())
|
||||||
<< " " << *$6 << "\n";
|
*O << *$2 << " = ";
|
||||||
|
*O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
|
||||||
delete $2; delete $3; delete $4; $5.destroy(); delete $6;
|
delete $2; delete $3; delete $4; $5.destroy(); delete $6;
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
| ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
|
| ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
|
||||||
*O << *$2 << " " << *$3 << " " << *$4 << " " << *$5.newTy
|
if (!$2->empty())
|
||||||
<< " " << *$6 << "\n";
|
*O << *$2 << " = ";
|
||||||
|
*O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
|
||||||
delete $2; delete $3; delete $4; $5.destroy(); delete $6;
|
delete $2; delete $3; delete $4; $5.destroy(); delete $6;
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
| ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
|
| ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
|
||||||
*O << *$2 << " " << *$3 << " " << *$4 << " " << *$5.newTy
|
if (!$2->empty())
|
||||||
<< " " << *$6 << "\n";
|
*O << *$2 << " = ";
|
||||||
|
*O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
|
||||||
delete $2; delete $3; delete $4; $5.destroy(); delete $6;
|
delete $2; delete $3; delete $4; $5.destroy(); delete $6;
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
@ -907,7 +970,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
|
|||||||
TO LABEL ValueRef UNWIND LABEL ValueRef {
|
TO LABEL ValueRef UNWIND LABEL ValueRef {
|
||||||
*O << " ";
|
*O << " ";
|
||||||
if (!$1->empty())
|
if (!$1->empty())
|
||||||
*O << *$1;
|
*O << *$1 << " = ";
|
||||||
*O << *$2 << " " << *$3 << " " << *$4.newTy << " " << *$5 << " ("
|
*O << *$2 << " " << *$3 << " " << *$4.newTy << " " << *$5 << " ("
|
||||||
<< *$7 << ") " << *$9 << " " << *$10.newTy << " " << *$11 << " "
|
<< *$7 << ") " << *$9 << " " << *$10.newTy << " " << *$11 << " "
|
||||||
<< *$12 << " " << *$13.newTy << " " << *$14 << "\n";
|
<< *$12 << " " << *$13.newTy << " " << *$14 << "\n";
|
||||||
@ -941,6 +1004,8 @@ JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
|
|||||||
|
|
||||||
Inst
|
Inst
|
||||||
: OptAssign InstVal {
|
: OptAssign InstVal {
|
||||||
|
if (!$1->empty())
|
||||||
|
*$1 += " = ";
|
||||||
*$1 += *$2;
|
*$1 += *$2;
|
||||||
delete $2;
|
delete $2;
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -1012,16 +1077,16 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
|||||||
delete $1; $2.destroy(); $4.destroy();
|
delete $1; $2.destroy(); $4.destroy();
|
||||||
}
|
}
|
||||||
| CastOps ResolvedVal TO Types {
|
| CastOps ResolvedVal TO Types {
|
||||||
const char *opcode = $1->c_str();
|
|
||||||
std::string source = *$2.val;
|
std::string source = *$2.val;
|
||||||
|
TypeInfo SrcTy = $2.type;
|
||||||
|
TypeInfo DstTy = $4;
|
||||||
|
ResolveType(DstTy);
|
||||||
|
$$ = new std::string();
|
||||||
if (*$1 == "cast") {
|
if (*$1 == "cast") {
|
||||||
std::string upgrade = getCastUpgrade(source, $2.type, $4, false);
|
*$$ += getCastUpgrade(source, SrcTy, DstTy, false);
|
||||||
if (!upgrade.empty())
|
} else {
|
||||||
*O << " " << upgrade << "\n";
|
*$$ += *$1 + " " + source + " to " + *DstTy.newTy;
|
||||||
opcode = getCastOpcode(source, $2.type, $4);
|
|
||||||
}
|
}
|
||||||
$$ = new std::string(opcode);
|
|
||||||
*$$ += " " + source + " " + *$3 + " " + *$4.newTy;
|
|
||||||
delete $1; $2.destroy();
|
delete $1; $2.destroy();
|
||||||
delete $3; $4.destroy();
|
delete $3; $4.destroy();
|
||||||
}
|
}
|
||||||
@ -1129,7 +1194,7 @@ MemoryInst : MALLOC Types OptCAlign {
|
|||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| GETELEMENTPTR Types ValueRef IndexList {
|
| GETELEMENTPTR Types ValueRef IndexList {
|
||||||
*$1 += *$2.newTy + " " + *$3 + " " + *$4;
|
*$1 += " " + *$2.newTy + " " + *$3 + " " + *$4;
|
||||||
$2.destroy(); delete $3; delete $4;
|
$2.destroy(); delete $3; delete $4;
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user