447 changes: 0 additions & 447 deletions src/access.c

This file was deleted.

412 changes: 412 additions & 0 deletions src/access.d

Large diffs are not rendered by default.

686 changes: 686 additions & 0 deletions src/aggregate.d

Large diffs are not rendered by default.

48 changes: 27 additions & 21 deletions src/aggregate.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "dsymbol.h"
#include "declaration.h"
#include "objc.h"

class Identifier;
class Type;
Expand Down Expand Up @@ -80,15 +81,15 @@ class AggregateDeclaration : public ScopeDsymbol
Sizeok sizeok; // set when structsize contains valid data
Dsymbol *deferred; // any deferred semantic2() or semantic3() symbol
bool isdeprecated; // true if deprecated
bool mutedeprecation; // true while analysing RTInfo to avoid deprecation message

Dsymbol *enclosing; /* !=NULL if is nested
* pointing to the dsymbol that directly enclosing it.
* 1. The function that enclosing it (nested struct and class)
* 2. The class that enclosing it (nested class only)
* 3. If enclosing aggregate is template, its enclosing dsymbol.
* See AggregateDeclaraton::makeNested for the details.
*/

/* !=NULL if is nested
* pointing to the dsymbol that directly enclosing it.
* 1. The function that enclosing it (nested struct and class)
* 2. The class that enclosing it (nested class only)
* 3. If enclosing aggregate is template, its enclosing dsymbol.
* See AggregateDeclaraton::makeNested for the details.
*/
Dsymbol *enclosing;
VarDeclaration *vthis; // 'this' parameter if this aggregate is nested
// Special member functions
FuncDeclarations invs; // Array of invariants
Expand All @@ -97,9 +98,12 @@ class AggregateDeclaration : public ScopeDsymbol
DeleteDeclaration *aggDelete; // deallocator

Dsymbol *ctor; // CtorDeclaration or TemplateDeclaration
CtorDeclaration *defaultCtor; // default constructor - should have no arguments, because
// it would be stored in TypeInfo_Class.defaultConstructor
Dsymbol *aliasthis; // forward unresolved lookups to aliasthis

// default constructor - should have no arguments, because
// it would be stored in TypeInfo_Class.defaultConstructor
CtorDeclaration *defaultCtor;

Dsymbol *aliasthis; // forward unresolved lookups to aliasthis
bool noDefaultCtor; // no default construction

FuncDeclarations dtors; // Array of destructors
Expand All @@ -113,23 +117,23 @@ class AggregateDeclaration : public ScopeDsymbol
void semantic3(Scope *sc);
unsigned size(Loc loc);
virtual void finalizeSize(Scope *sc) = 0;
bool checkOverlappedFields();
bool fill(Loc loc, Expressions *elements, bool ctorinit);
static void alignmember(structalign_t salign, unsigned size, unsigned *poffset);
static unsigned placeField(unsigned *nextoffset,
unsigned memsize, unsigned memalignsize, structalign_t memalign,
unsigned *paggsize, unsigned *paggalignsize, bool isunion);
Type *getType();
int firstFieldInUnion(int indx); // first field in union that includes indx
int numFieldsInUnion(int firstIndex); // #fields in union starting at index
bool isDeprecated(); // is aggregate deprecated?
bool muteDeprecationMessage(); // disable deprecation message on Dsymbol?
bool isNested();
void makeNested();
bool isExport();
Dsymbol *searchCtor();

Prot prot();

Type *handleType() { return type; } // 'this' type
// 'this' type
Type *handleType() { return type; }

// Back end
Symbol *stag; // tag symbol for debug data
Expand Down Expand Up @@ -183,7 +187,6 @@ class StructDeclaration : public AggregateDeclaration
const char *kind();
void finalizeSize(Scope *sc);
bool fit(Loc loc, Scope *sc, Expressions *elements, Type *stype);
bool fill(Loc loc, Expressions *elements, bool ctorinit);
bool isPOD();

StructDeclaration *isStructDeclaration() { return this; }
Expand All @@ -204,12 +207,13 @@ class UnionDeclaration : public StructDeclaration
struct BaseClass
{
Type *type; // (before semantic processing)
Prot protection; // protection for the base interface
Prot protection; // protection for the base interface

ClassDeclaration *base;
ClassDeclaration *sym;
unsigned offset; // 'this' pointer offset
FuncDeclarations vtbl; // for interfaces: Array of FuncDeclaration's
// making up the vtbl[]
// for interfaces: Array of FuncDeclaration's
// making up the vtbl[]
FuncDeclarations vtbl;

size_t baseInterfaces_dim;
// if BaseClass is an interface, these
Expand Down Expand Up @@ -271,6 +275,7 @@ class ClassDeclaration : public AggregateDeclaration
bool isabstract; // true if abstract class
int inuse; // to prevent recursive attempts
Baseok baseok; // set the progress of base classes resolving
Objc_ClassDeclaration objc;

ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses, bool inObject = false);
Dsymbol *syntaxCopy(Dsymbol *s);
Expand All @@ -287,6 +292,7 @@ class ClassDeclaration : public AggregateDeclaration
bool isFuncHidden(FuncDeclaration *fd);
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
void interfaceSemantic(Scope *sc);
unsigned setBaseInterfaceOffsets(unsigned baseOffset);
bool isCOMclass();
virtual bool isCOMinterface();
bool isCPPclass();
Expand Down
154 changes: 0 additions & 154 deletions src/aliasthis.c

This file was deleted.

164 changes: 164 additions & 0 deletions src/aliasthis.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt

module ddmd.aliasthis;

import ddmd.aggregate;
import ddmd.declaration;
import ddmd.dscope;
import ddmd.dsymbol;
import ddmd.errors;
import ddmd.expression;
import ddmd.func;
import ddmd.globals;
import ddmd.hdrgen;
import ddmd.identifier;
import ddmd.mtype;
import ddmd.opover;
import ddmd.root.outbuffer;
import ddmd.tokens;
import ddmd.visitor;

/***********************************************************
* alias ident this;
*/
extern (C++) final class AliasThis : Dsymbol
{
public:
Identifier ident;

extern (D) this(Loc loc, Identifier ident)
{
super(null); // it's anonymous (no identifier)
this.loc = loc;
this.ident = ident;
}

override Dsymbol syntaxCopy(Dsymbol s)
{
assert(!s);
/* Since there is no semantic information stored here,
* we don't need to copy it.
*/
return this;
}

override void semantic(Scope* sc)
{
Dsymbol p = sc.parent.pastMixin();
AggregateDeclaration ad = p.isAggregateDeclaration();
if (!ad)
{
.error(loc, "alias this can only be a member of aggregate, not %s %s", p.kind(), p.toChars());
return;
}
assert(ad.members);
Dsymbol s = ad.search(loc, ident);
if (!s)
{
s = sc.search(loc, ident, null);
if (s)
.error(loc, "%s is not a member of %s", s.toChars(), ad.toChars());
else
.error(loc, "undefined identifier %s", ident.toChars());
return;
}
else if (ad.aliasthis && s != ad.aliasthis)
{
.error(loc, "there can be only one alias this");
return;
}
if (ad.type.ty == Tstruct && (cast(TypeStruct)ad.type).sym != ad)
{
AggregateDeclaration ad2 = (cast(TypeStruct)ad.type).sym;
assert(ad2.type == Type.terror);
ad.aliasthis = ad2.aliasthis;
return;
}
/* disable the alias this conversion so the implicit conversion check
* doesn't use it.
*/
ad.aliasthis = null;
Dsymbol sx = s;
if (sx.isAliasDeclaration())
sx = sx.toAlias();
Declaration d = sx.isDeclaration();
if (d && !d.isTupleDeclaration())
{
Type t = d.type;
assert(t);
if (ad.type.implicitConvTo(t) > MATCHnomatch)
{
.error(loc, "alias this is not reachable as %s already converts to %s", ad.toChars(), t.toChars());
}
}
ad.aliasthis = s;
}

override const(char)* kind()
{
return "alias this";
}

AliasThis isAliasThis()
{
return this;
}

override void accept(Visitor v)
{
v.visit(this);
}
}

extern (C++) Expression resolveAliasThis(Scope* sc, Expression e, bool gag = false)
{
AggregateDeclaration ad = isAggregate(e.type);
if (ad && ad.aliasthis)
{
uint olderrors = gag ? global.startGagging() : 0;
Loc loc = e.loc;
Type tthis = (e.op == TOKtype ? e.type : null);
e = new DotIdExp(loc, e, ad.aliasthis.ident);
e = e.semantic(sc);
if (tthis && ad.aliasthis.needThis())
{
if (e.op == TOKvar)
{
if (FuncDeclaration f = (cast(VarExp)e).var.isFuncDeclaration())
{
// Bugzilla 13009: Support better match for the overloaded alias this.
Type t;
f = f.overloadModMatch(loc, tthis, t);
if (f && t)
{
e = new VarExp(loc, f, 0); // use better match
e = new CallExp(loc, e);
goto L1;
}
}
}
/* non-@property function is not called inside typeof(),
* so resolve it ahead.
*/
{
int save = sc.intypeof;
sc.intypeof = 1; // bypass "need this" error check
e = resolveProperties(sc, e);
sc.intypeof = save;
}
L1:
e = new TypeExp(loc, new TypeTypeof(loc, e));
e = e.semantic(sc);
}
e = resolveProperties(sc, e);
if (gag && global.endGagging(olderrors))
e = null;
}
return e;
}
145 changes: 0 additions & 145 deletions src/apply.c

This file was deleted.

145 changes: 145 additions & 0 deletions src/apply.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt

module ddmd.apply;

import ddmd.arraytypes;
import ddmd.expression;
import ddmd.visitor;

/**************************************
* An Expression tree walker that will visit each Expression e in the tree,
* in depth-first evaluation order, and call fp(e,param) on it.
* fp() signals whether the walking continues with its return value:
* Returns:
* 0 continue
* 1 done
* It's a bit slower than using virtual functions, but more encapsulated and less brittle.
* Creating an iterator for this would be much more complex.
*/
extern (C++) final class PostorderExpressionVisitor : StoppableVisitor
{
alias visit = super.visit;
public:
StoppableVisitor v;

extern (D) this(StoppableVisitor v)
{
this.v = v;
}

bool doCond(Expression e)
{
if (!stop && e)
e.accept(this);
return stop;
}

bool doCond(Expressions* e)
{
if (!e)
return false;
for (size_t i = 0; i < e.dim && !stop; i++)
doCond((*e)[i]);
return stop;
}

bool applyTo(Expression e)
{
e.accept(v);
stop = v.stop;
return true;
}

override void visit(Expression e)
{
applyTo(e);
}

override void visit(NewExp e)
{
//printf("NewExp::apply(): %s\n", toChars());
doCond(e.thisexp) || doCond(e.newargs) || doCond(e.arguments) || applyTo(e);
}

override void visit(NewAnonClassExp e)
{
//printf("NewAnonClassExp::apply(): %s\n", toChars());
doCond(e.thisexp) || doCond(e.newargs) || doCond(e.arguments) || applyTo(e);
}

override void visit(UnaExp e)
{
doCond(e.e1) || applyTo(e);
}

override void visit(BinExp e)
{
doCond(e.e1) || doCond(e.e2) || applyTo(e);
}

override void visit(AssertExp e)
{
//printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
doCond(e.e1) || doCond(e.msg) || applyTo(e);
}

override void visit(CallExp e)
{
//printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
doCond(e.e1) || doCond(e.arguments) || applyTo(e);
}

override void visit(ArrayExp e)
{
//printf("ArrayExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
doCond(e.e1) || doCond(e.arguments) || applyTo(e);
}

override void visit(SliceExp e)
{
doCond(e.e1) || doCond(e.lwr) || doCond(e.upr) || applyTo(e);
}

override void visit(ArrayLiteralExp e)
{
doCond(e.basis) || doCond(e.elements) || applyTo(e);
}

override void visit(AssocArrayLiteralExp e)
{
doCond(e.keys) || doCond(e.values) || applyTo(e);
}

override void visit(StructLiteralExp e)
{
if (e.stageflags & stageApply)
return;
int old = e.stageflags;
e.stageflags |= stageApply;
doCond(e.elements) || applyTo(e);
e.stageflags = old;
}

override void visit(TupleExp e)
{
doCond(e.e0) || doCond(e.exps) || applyTo(e);
}

override void visit(CondExp e)
{
doCond(e.econd) || doCond(e.e1) || doCond(e.e2) || applyTo(e);
}
}

extern (C++) bool walkPostorder(Expression e, StoppableVisitor v)
{
scope PostorderExpressionVisitor pv = new PostorderExpressionVisitor(v);
e.accept(pv);
return v.stop;
}
491 changes: 0 additions & 491 deletions src/argtypes.c

This file was deleted.

448 changes: 448 additions & 0 deletions src/argtypes.d

Large diffs are not rendered by default.

638 changes: 0 additions & 638 deletions src/arrayop.c

This file was deleted.

646 changes: 646 additions & 0 deletions src/arrayop.d

Large diffs are not rendered by default.

53 changes: 53 additions & 0 deletions src/arraytypes.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt

module ddmd.arraytypes;

import ddmd.aggregate;
import ddmd.backend;
import ddmd.dclass;
import ddmd.declaration;
import ddmd.dmodule;
import ddmd.dsymbol;
import ddmd.dtemplate;
import ddmd.expression;
import ddmd.func;
import ddmd.globals;
import ddmd.identifier;
import ddmd.init;
import ddmd.mtype;
import ddmd.root.array;
import ddmd.root.file;
import ddmd.root.rootobject;
import ddmd.statement;

alias Strings = Array!(const(char)*);
alias Identifiers = Array!(Identifier);
alias TemplateParameters = Array!(TemplateParameter);
alias Expressions = Array!(Expression);
alias Statements = Array!(Statement);
alias BaseClasses = Array!(BaseClass*);
alias ClassDeclarations = Array!(ClassDeclaration);
alias Dsymbols = Array!(Dsymbol);
alias Objects = Array!(RootObject);
alias FuncDeclarations = Array!(FuncDeclaration);
alias Parameters = Array!(Parameter);
alias Initializers = Array!(Initializer);
alias VarDeclarations = Array!(VarDeclaration);
alias Types = Array!(Type);
alias Catches = Array!(Catch);
alias StaticDtorDeclarations = Array!(StaticDtorDeclaration);
alias SharedStaticDtorDeclarations = Array!(SharedStaticDtorDeclaration);
alias AliasDeclarations = Array!(AliasDeclaration);
alias Modules = Array!(Module);
alias CaseStatements = Array!(CaseStatement);
alias ScopeStatements = Array!(ScopeStatement);
alias GotoCaseStatements = Array!(GotoCaseStatement);
alias ReturnStatements = Array!(ReturnStatement);
alias GotoStatements = Array!(GotoStatement);
alias TemplateInstances = Array!(TemplateInstance);
4 changes: 0 additions & 4 deletions src/arraytypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,4 @@ typedef Array<class GotoStatement *> GotoStatements;

typedef Array<class TemplateInstance *> TemplateInstances;

typedef Array<struct block *> Blocks;

typedef Array<struct Symbol *> Symbols;

#endif
1,497 changes: 0 additions & 1,497 deletions src/attrib.c

This file was deleted.

1,443 changes: 1,443 additions & 0 deletions src/attrib.d

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions src/attrib.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ class StorageClassDeclaration : public AttribDeclaration
Scope *newScope(Scope *sc);
bool oneMember(Dsymbol **ps, Identifier *ident);

static const char *stcToChars(char tmp[], StorageClass& stc);
static void stcToCBuffer(OutBuffer *buf, StorageClass stc);
void accept(Visitor *v) { v->visit(this); }
};

Expand Down Expand Up @@ -130,12 +128,16 @@ class AnonDeclaration : public AttribDeclaration
bool isunion;
structalign_t alignment;
int sem; // 1 if successful semantic()
unsigned anonoffset; // offset of anonymous struct
unsigned anonstructsize; // size of anonymous struct
unsigned anonalignsize; // size of anonymous struct for alignment purposes

AnonDeclaration(Loc loc, bool isunion, Dsymbols *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
const char *kind();
AnonDeclaration *isAnonDeclaration() { return this; }
void accept(Visitor *v) { v->visit(this); }
};

Expand Down
156 changes: 151 additions & 5 deletions src/backend.d
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,171 @@

module ddmd.backend;

import ddmd.aggregate, ddmd.dmodule, ddmd.dscope, ddmd.expression, ddmd.lib, ddmd.mtype, ddmd.root.file;
import ddmd.aggregate;
import ddmd.dmodule;
import ddmd.dscope;
import ddmd.expression;
import ddmd.lib;
import ddmd.mtype;
import ddmd.root.file;

struct Symbol;
struct TYPE;
alias type = TYPE;
struct code;
struct block;
struct Blockx;
struct elem;

extern extern (C++) void backend_init();
extern extern (C++) void backend_term();
extern extern (C++) void obj_start(char* srcfile);
extern extern (C++) void obj_end(Library library, File* objfile);
extern extern (C++) void obj_write_deferred(Library library);

extern extern (C++) Type getTypeInfoType(Type t, Scope* sc);
extern extern (C++) Expression getInternalTypeInfo(Type t, Scope* sc);
extern extern (C++) void genObjFile(Module m, bool multiobj);

extern extern (C++) Symbol* toInitializer(AggregateDeclaration sd);
extern extern (C++) Symbol* toModuleArray(Module m);
extern extern (C++) Symbol* toModuleAssert(Module m);
extern extern (C++) Symbol* toModuleUnittest(Module m);

// type.h


alias tym_t = uint;
alias mangle_t = ubyte;
alias targ_size_t = ulong;

struct PARAM;
struct Classsym;
struct LIST;
alias list_t = LIST*;
alias type = TYPE;

extern extern (C++) type* type_fake(tym_t);
extern extern (C++) uint totym(Type tx);
extern extern (C++) void type_incCount(type* t);
extern extern (C++) void type_setIdent(type* t, char* ident);

extern extern (C++) type* type_alloc(tym_t);
extern extern (C++) type* type_allocn(tym_t, type* tn);

extern extern (C++) type* type_pointer(type* tnext);
extern extern (C++) type* type_dyn_array(type* tnext);
extern extern (C) type* type_static_array(targ_size_t dim, type* tnext);
extern extern (C++) type* type_assoc_array(type* tkey, type* tvalue);
extern extern (C++) type* type_delegate(type* tnext);
extern extern (C) type* type_function(tym_t tyf, type** ptypes, size_t nparams, bool variadic, type* tret);
extern extern (C++) type* type_enum(const(char)* name, type* tbase);
extern extern (C++) type* type_struct_class(const(char)* name, uint alignsize, uint structsize,
type* arg1type, type* arg2type, bool isUnion, bool isClass, bool isPOD);

extern extern (C++) void symbol_struct_addField(Symbol* s, const(char)* name, type* t, uint offset);

enum mTYbasic = 0xFF; /* bit mask for basic types */
enum mTYconst = 0x100;
enum mTYimmutable = 0x00080000; // immutable data
enum mTYshared = 0x00100000; // shared data

tym_t tybasic(tym_t ty) { return ty & mTYbasic; }

// Return true if type is a struct, class or union
bool type_struct(type* t) { return tybasic(t.Tty) == TYstruct; }

struct TYPE
{
debug ushort id;

tym_t Tty; /* mask (TYxxx) */
ushort Tflags; // TFxxxxx

mangle_t Tmangle; // name mangling

uint Tcount; // # pointing to this type
TYPE* Tnext; // next in list
// TYenum: gives base type
union
{
targ_size_t Tdim; // TYarray: # of elements in array
elem* Tel; // TFvla: gives dimension (NULL if '*')
PARAM* Tparamtypes; // TYfunc, TYtemplate: types of function parameters
Classsym* Ttag; // TYstruct,TYmemptr: tag symbol
// TYenum,TYvtshape: tag symbol
char* Tident; // TYident: identifier
TYPE* Tkey; // typtr: key type for associative arrays
}

list_t Texcspec; // tyfunc(): list of types of exception specification
}

enum
{
TYbool = 0,
TYchar = 1,
TYschar = 2, // signed char
TYuchar = 3, // unsigned char
TYchar8 = 4,
TYchar16 = 5,
TYshort = 6,
TYwchar_t = 7,
TYushort = 8, // unsigned short
TYenum = 9, // enumeration value
TYint = 0xA,
TYuint = 0xB, // unsigned
TYlong = 0xC,
TYulong = 0xD, // unsigned long
TYdchar = 0xE, // 32 bit Unicode char
TYllong = 0xF, // 64 bit long
TYullong = 0x10, // 64 bit unsigned long
TYfloat = 0x11, // 32 bit real
TYdouble = 0x12, // 64 bit real

// long double is mapped to either of the following at runtime:
TYdouble_alias = 0x13, // 64 bit real (but distinct for overload purposes)
TYldouble = 0x14, // 80 bit real

// Add imaginary and complex types for D and C99
TYifloat = 0x15,
TYidouble = 0x16,
TYildouble = 0x17,
TYcfloat = 0x18,
TYcdouble = 0x19,
TYcldouble = 0x1A,

TYnullptr = 0x1C,
TYnptr = 0x1D, // data segment relative pointer
TYref = 0x24, // reference to another type
TYvoid = 0x25,
TYstruct = 0x26, // watch tyaggregate()
TYarray = 0x27, // watch tyaggregate()
TYnfunc = 0x28, // near C func
TYnpfunc = 0x2A, // near Cpp func
TYnsfunc = 0x2C, // near stdcall func
TYifunc = 0x2E, // interrupt func
TYptr = 0x33, // generic pointer type
TYmfunc = 0x37, // NT C++ member func
TYjfunc = 0x38, // LINKd D function
TYhfunc = 0x39, // C function with hidden parameter
TYnref = 0x3A, // near reference

TYcent = 0x3C, // 128 bit signed integer
TYucent = 0x3D, // 128 bit unsigned integer

// SIMD vector types // D type
TYfloat4 = 0x3E, // float[4]
TYdouble2 = 0x3F, // double[2]
TYschar16 = 0x40, // byte[16]
TYuchar16 = 0x41, // ubyte[16]
TYshort8 = 0x42, // short[8]
TYushort8 = 0x43, // ushort[8]
TYlong4 = 0x44, // int[4]
TYulong4 = 0x45, // uint[4]
TYllong2 = 0x46, // long[2]
TYullong2 = 0x47, // ulong[2]

// // MARS types
// #define TYaarray TYnptr
// #define TYdelegate (I64 ? TYcent : TYllong)
// #define TYdarray (I64 ? TYucent : TYullong)

TYMAX = 0x48,
}
183 changes: 89 additions & 94 deletions src/backend/backconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,11 @@ void out_config_init(
config.flags |= CFGromable; // put switch tables in code segment
}
config.flags |= CFGnoebp;
config.flags |= CFGalwaysframe;
if (!exe)
{
config.flags3 |= CFG3pic;
config.flags |= CFGalwaysframe; // PIC needs a frame for TLS fixups
}
config.objfmt = OBJ_ELF;
#endif
#if TARGET_OSX
Expand All @@ -114,9 +116,12 @@ void out_config_init(
else
config.exe = EX_OSX;
config.flags |= CFGnoebp;
config.flags |= CFGalwaysframe;
if (!exe)
if (!exe)
{
config.flags3 |= CFG3pic;
config.flags |= CFGalwaysframe; // PIC needs a frame for TLS fixups
}
config.flags |= CFGromable; // put switch tables in code segment
config.objfmt = OBJ_MACH;
#endif
Expand All @@ -132,9 +137,11 @@ void out_config_init(
config.flags |= CFGromable; // put switch tables in code segment
}
config.flags |= CFGnoebp;
config.flags |= CFGalwaysframe;
if (!exe)
{
config.flags3 |= CFG3pic;
config.flags |= CFGalwaysframe; // PIC needs a frame for TLS fixups
}
config.objfmt = OBJ_ELF;
#endif
#if TARGET_OPENBSD
Expand Down Expand Up @@ -295,66 +302,60 @@ void util_set32()
tyequiv[TYint] = TYlong;
tyequiv[TYuint] = TYulong;

for (int i = 0; i < 1; ++i)
{ tysize[TYenum + i] = LONGSIZE;
tysize[TYint + i] = LONGSIZE;
tysize[TYuint + i] = LONGSIZE;
tysize[TYnullptr + i] = LONGSIZE;
tysize[TYjhandle + i] = LONGSIZE;
tysize[TYnptr + i] = LONGSIZE;
tysize[TYnref + i] = LONGSIZE;
tysize[TYenum] = LONGSIZE;
tysize[TYint ] = LONGSIZE;
tysize[TYuint] = LONGSIZE;
tysize[TYnullptr] = LONGSIZE;
tysize[TYnptr] = LONGSIZE;
tysize[TYnref] = LONGSIZE;
#if TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS
tysize[TYldouble + i] = 12;
tysize[TYildouble + i] = 12;
tysize[TYcldouble + i] = 24;
tysize[TYldouble] = 12;
tysize[TYildouble] = 12;
tysize[TYcldouble] = 24;
#elif TARGET_OSX
tysize[TYldouble + i] = 16;
tysize[TYildouble + i] = 16;
tysize[TYcldouble + i] = 32;
tysize[TYldouble] = 16;
tysize[TYildouble] = 16;
tysize[TYcldouble] = 32;
#elif TARGET_WINDOS
tysize[TYldouble + i] = 10;
tysize[TYildouble + i] = 10;
tysize[TYcldouble + i] = 20;
tysize[TYldouble] = 10;
tysize[TYildouble] = 10;
tysize[TYcldouble] = 20;
#else
assert(0);
assert(0);
#endif
#if TARGET_SEGMENTED
tysize[TYsptr + i] = LONGSIZE;
tysize[TYcptr + i] = LONGSIZE;
tysize[TYfptr + i] = 6; // NOTE: There are codgen test that check
tysize[TYvptr + i] = 6; // tysize[x] == tysize[TYfptr] so don't set
tysize[TYfref + i] = 6; // tysize[TYfptr] to tysize[TYnptr]
tysize[TYsptr] = LONGSIZE;
tysize[TYcptr] = LONGSIZE;
tysize[TYfptr] = 6; // NOTE: There are codgen test that check
tysize[TYvptr] = 6; // tysize[x] == tysize[TYfptr] so don't set
tysize[TYfref] = 6; // tysize[TYfptr] to tysize[TYnptr]
#endif
}

for (int i = 0; i < 1; ++i)
{ tyalignsize[TYenum + i] = LONGSIZE;
tyalignsize[TYint + i] = LONGSIZE;
tyalignsize[TYuint + i] = LONGSIZE;
tyalignsize[TYnullptr + i] = LONGSIZE;
tyalignsize[TYjhandle + i] = LONGSIZE;
tyalignsize[TYnref + i] = LONGSIZE;
tyalignsize[TYnptr + i] = LONGSIZE;
tyalignsize[TYenum] = LONGSIZE;
tyalignsize[TYint ] = LONGSIZE;
tyalignsize[TYuint] = LONGSIZE;
tyalignsize[TYnullptr] = LONGSIZE;
tyalignsize[TYnref] = LONGSIZE;
tyalignsize[TYnptr] = LONGSIZE;
#if TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS
tyalignsize[TYldouble + i] = 4;
tyalignsize[TYildouble + i] = 4;
tyalignsize[TYcldouble + i] = 4;
tyalignsize[TYldouble] = 4;
tyalignsize[TYildouble] = 4;
tyalignsize[TYcldouble] = 4;
#elif TARGET_OSX
tyalignsize[TYldouble + i] = 16;
tyalignsize[TYildouble + i] = 16;
tyalignsize[TYcldouble + i] = 16;
tyalignsize[TYldouble] = 16;
tyalignsize[TYildouble] = 16;
tyalignsize[TYcldouble] = 16;
#elif TARGET_WINDOS
tyalignsize[TYldouble + i] = 2;
tyalignsize[TYildouble + i] = 2;
tyalignsize[TYcldouble + i] = 2;
tyalignsize[TYldouble] = 2;
tyalignsize[TYildouble] = 2;
tyalignsize[TYcldouble] = 2;
#else
assert(0);
assert(0);
#endif
#if TARGET_SEGMENTED
tyalignsize[TYsptr + i] = LONGSIZE;
tyalignsize[TYcptr + i] = LONGSIZE;
tyalignsize[TYsptr] = LONGSIZE;
tyalignsize[TYcptr] = LONGSIZE;
#endif
}
}

/*******************************
Expand All @@ -370,66 +371,60 @@ void util_set64()
tyequiv[TYint] = TYlong;
tyequiv[TYuint] = TYulong;

for (int i = 0; i < 1; ++i)
{ tysize[TYenum + i] = LONGSIZE;
tysize[TYint + i] = LONGSIZE;
tysize[TYuint + i] = LONGSIZE;
tysize[TYnullptr + i] = 8;
tysize[TYjhandle + i] = 8;
tysize[TYnptr + i] = 8;
tysize[TYnref + i] = 8;
tysize[TYenum] = LONGSIZE;
tysize[TYint ] = LONGSIZE;
tysize[TYuint] = LONGSIZE;
tysize[TYnullptr] = 8;
tysize[TYnptr] = 8;
tysize[TYnref] = 8;
#if TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS || TARGET_OSX
tysize[TYldouble + i] = 16;
tysize[TYildouble + i] = 16;
tysize[TYcldouble + i] = 32;
tysize[TYldouble] = 16;
tysize[TYildouble] = 16;
tysize[TYcldouble] = 32;
#elif TARGET_WINDOS
tysize[TYldouble + i] = 10;
tysize[TYildouble + i] = 10;
tysize[TYcldouble + i] = 20;
tysize[TYldouble] = 10;
tysize[TYildouble] = 10;
tysize[TYcldouble] = 20;
#else
assert(0);
assert(0);
#endif
#if TARGET_SEGMENTED
tysize[TYsptr + i] = 8;
tysize[TYcptr + i] = 8;
tysize[TYfptr + i] = 10; // NOTE: There are codgen test that check
tysize[TYvptr + i] = 10; // tysize[x] == tysize[TYfptr] so don't set
tysize[TYfref + i] = 10; // tysize[TYfptr] to tysize[TYnptr]
tysize[TYsptr] = 8;
tysize[TYcptr] = 8;
tysize[TYfptr] = 10; // NOTE: There are codgen test that check
tysize[TYvptr] = 10; // tysize[x] == tysize[TYfptr] so don't set
tysize[TYfref] = 10; // tysize[TYfptr] to tysize[TYnptr]
#endif
}

for (int i = 0; i < 1; ++i)
{ tyalignsize[TYenum + i] = LONGSIZE;
tyalignsize[TYint + i] = LONGSIZE;
tyalignsize[TYuint + i] = LONGSIZE;
tyalignsize[TYnullptr + i] = 8;
tyalignsize[TYjhandle + i] = 8;
tyalignsize[TYnptr + i] = 8;
tyalignsize[TYnref + i] = 8;
tyalignsize[TYenum] = LONGSIZE;
tyalignsize[TYint ] = LONGSIZE;
tyalignsize[TYuint] = LONGSIZE;
tyalignsize[TYnullptr] = 8;
tyalignsize[TYnptr] = 8;
tyalignsize[TYnref] = 8;
#if TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS
tyalignsize[TYldouble + i] = 16;
tyalignsize[TYildouble + i] = 16;
tyalignsize[TYcldouble + i] = 16;
tyalignsize[TYldouble] = 16;
tyalignsize[TYildouble] = 16;
tyalignsize[TYcldouble] = 16;
#elif TARGET_OSX
tyalignsize[TYldouble + i] = 16;
tyalignsize[TYildouble + i] = 16;
tyalignsize[TYcldouble + i] = 16;
tyalignsize[TYldouble] = 16;
tyalignsize[TYildouble] = 16;
tyalignsize[TYcldouble] = 16;
#elif TARGET_WINDOS
tyalignsize[TYldouble + i] = 2;
tyalignsize[TYildouble + i] = 2;
tyalignsize[TYcldouble + i] = 2;
tyalignsize[TYldouble] = 2;
tyalignsize[TYildouble] = 2;
tyalignsize[TYcldouble] = 2;
#else
assert(0);
assert(0);
#endif
#if TARGET_SEGMENTED
tyalignsize[TYsptr + i] = 8;
tyalignsize[TYcptr + i] = 8;
tyalignsize[TYfptr + i] = 8;
tyalignsize[TYvptr + i] = 8;
tyalignsize[TYfref + i] = 8;
tyalignsize[TYsptr] = 8;
tyalignsize[TYcptr] = 8;
tyalignsize[TYfptr] = 8;
tyalignsize[TYvptr] = 8;
tyalignsize[TYfref] = 8;
#endif
tytab[TYjfunc + i] &= ~TYFLpascal; // set so caller cleans the stack (as in C)
}
tytab[TYjfunc] &= ~TYFLpascal; // set so caller cleans the stack (as in C)

TYptrdiff = TYllong;
TYsize = TYullong;
Expand Down
40 changes: 18 additions & 22 deletions src/backend/blockopt.c
Original file line number Diff line number Diff line change
Expand Up @@ -584,14 +584,14 @@ void blockopt(int iter)
count = 0;
do
{
//printf("changes = %d, count = %d, dfotop = %d\n",changes,count,dfotop);
//printf("changes = %d, count = %d, dfotop = %d\n",go.changes,count,dfotop);
#if MARS
util_progress();
#else
if (controlc_saw)
util_exit(EXIT_BREAK);
#endif
changes = 0;
go.changes = 0;
bropt(); // branch optimization
brrear(); // branch rearrangement
blident(); // combine identical blocks
Expand All @@ -608,7 +608,7 @@ void blockopt(int iter)
assert(count < iterationLimit);
count++;
} while (mergeblks()); /* merge together blocks */
} while (changes);
} while (go.changes);
#ifdef DEBUG
if (debugw)
for (b = startblock; b; b = b->Bnext)
Expand Down Expand Up @@ -867,7 +867,7 @@ void brcombine()
}
}
if (anychanges)
{ changes++;
{ go.changes++;
continue;
}
} while (0);
Expand Down Expand Up @@ -907,7 +907,7 @@ STATIC void bropt()
n->Ety = tym;
b->Bsucc = list_reverse(b->Bsucc);
cmes("CHANGE: if (!e)\n");
changes++;
go.changes++;
}

/* Take care of IF (constant) */
Expand All @@ -928,7 +928,7 @@ STATIC void bropt()
/* delete elem if it has no side effects */
b->Belem = doptelem(b->Belem,GOALnone | GOALagain);
cmes("CHANGE: if (const)\n");
changes++;
go.changes++;
}

/* Look for both destinations being the same */
Expand All @@ -939,7 +939,7 @@ STATIC void bropt()
list_subtract(&(b->Bsucc),db);
list_subtract(&(db->Bpred),b);
cmes("CHANGE: if (e) goto L1; else goto L1;\n");
changes++;
go.changes++;
}
}
else if (b->BC == BCswitch)
Expand Down Expand Up @@ -985,7 +985,7 @@ STATIC void bropt()
b->BC = BCgoto;
b->Belem = doptelem(b->Belem,GOALnone | GOALagain);
cmes("CHANGE: switch (const)\n");
changes++;
go.changes++;
}
}
}
Expand Down Expand Up @@ -1176,7 +1176,7 @@ STATIC void elimblks()
b->Bnext = bf;
bf = b; /* prepend to deferred list to free */
cmes2("CHANGE: block %p deleted\n",b);
changes++;
go.changes++;
}
else
pb = &((*pb)->Bnext);
Expand Down Expand Up @@ -1338,7 +1338,7 @@ STATIC void blident()
/* successors match */
/* elems match */
if (b->BC == bn->BC &&
//(!OPTIMIZER || !(mfoptim & MFtime) || !b->Bsucc) &&
//(!OPTIMIZER || !(go.mfoptim & MFtime) || !b->Bsucc) &&
(!OPTIMIZER || !(b->Bflags & BFLnomerg) || !b->Bsucc) &&
list_equal(b->Bsucc,bn->Bsucc) &&
#if SCPP || NTEXCEPTIONS
Expand Down Expand Up @@ -1456,7 +1456,7 @@ STATIC void blident()
dbg_printf("block B%d (%p) removed, it was same as B%d (%p)\n",
bn->Bdfoidx,bn,b->Bdfoidx,b);
#endif
changes++;
go.changes++;
break;
}
}
Expand All @@ -1470,7 +1470,7 @@ STATIC void blident()

STATIC void blreturn()
{
if (!(mfoptim & MFtime)) /* if optimized for space */
if (!(go.mfoptim & MFtime)) /* if optimized for space */
{
int retcount; /* number of return counts */
block *b;
Expand Down Expand Up @@ -1590,7 +1590,7 @@ STATIC void bltailmerge()
{
cmes("bltailmerge()\n");
assert(!PARSER && OPTIMIZER);
if (!(mfoptim & MFtime)) /* if optimized for space */
if (!(go.mfoptim & MFtime)) /* if optimized for space */
{
block *b;
block *bn;
Expand Down Expand Up @@ -1693,7 +1693,7 @@ STATIC void bltailmerge()
list_append(&b->Bsucc,bnew);
list_append(&bn->Bsucc,bnew);

changes++;
go.changes++;

/* Find all the expressions we can merge */
do
Expand Down Expand Up @@ -1786,7 +1786,7 @@ STATIC void brmin()
b->Bnext = bs;
#endif
cmes3("Moving block %p to appear after %p\n",bs,b);
changes++;
go.changes++;
break;

L2: ;
Expand Down Expand Up @@ -1928,7 +1928,7 @@ STATIC void brtailrecursion()
startblock = bs;

cmes("tail recursion\n");
changes++;
go.changes++;
return;
}
}
Expand Down Expand Up @@ -2057,7 +2057,7 @@ STATIC void emptyloops()
dbg_printf(" eliminated loop\n");
}
#endif
changes++;
go.changes++;
}
#else
// Find einc and erel
Expand Down Expand Up @@ -2094,7 +2094,7 @@ STATIC void emptyloops()
dbg_printf(" eliminated loop\n");
}
#endif
changes++;
go.changes++;
}
#endif
}
Expand Down Expand Up @@ -2156,10 +2156,6 @@ STATIC int funcsideeffect_walk(elem *e)
break;
goto Lside;

case OParray:
case OPfield:
goto Lside; // these can throw exceptions

// Note: we should allow assignments to local variables as
// not being a 'side effect'.

Expand Down
67 changes: 18 additions & 49 deletions src/backend/cc.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* For any other uses, please contact Digital Mars.
*/

#if __SC__
#if __DMC__
#pragma once
#endif

Expand Down Expand Up @@ -210,9 +210,6 @@ typedef struct Srcpos
#if M_UNIX
short Sfilnum; // file number
#endif
#if SOURCE_OFFSETS
unsigned long Sfiloff; // byte offset
#endif

void print(const char *func);
} Srcpos;
Expand Down Expand Up @@ -352,7 +349,7 @@ extern Cstate cstate;
// done on it, so it is stack and register variables.)
#define symbol_isintab(s) (sytab[(s)->Sclass] & SCSS)

#if defined(__SC__) || defined(_MSC_VER)
#if defined(__DMC__) || defined(_MSC_VER)
typedef char enum_SC;
#else
typedef enum SC enum_SC;
Expand Down Expand Up @@ -595,14 +592,13 @@ enum BC {
BCcatch = 11, // C++ catch block
BCjump = 12, // Belem specifies (near) address to jump to
BC_try = 13, // SEH: first block of try-except or try-finally
// Jupiter, Mars: try-catch or try-finally
// Mars: try-catch or try-finally
BC_filter = 14, // SEH exception-filter (always exactly one block)
BC_finally = 15, // first block of SEH termination-handler,
// or finally block
BC_ret = 16, // last block of SEH termination-handler or finally block
BC_except = 17, // first block of SEH exception-handler
BCjcatch = 18, // first block of Jupiter or Mars catch-block
BCjplace = 19, // Jupiter: placeholder
BCjcatch = 18, // first block of Mars catch-block
BCMAX
};

Expand Down Expand Up @@ -665,10 +661,8 @@ typedef struct FUNC_S
#define Fnteh 0x08 // uses NT Structured EH
#define Fdoinline 0x40 // do inline walk
#define Foverridden 0x80 // ignore for overriding purposes
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
#define Fnowrite 0x100 // SCinline should never output definition
#else
#define Fjmonitor 0x100 // Jupiter synchronized function
#if MARS && TARGET_WINDOS
#define Fjmonitor 0x100 // Mars synchronized function
#endif
#define Fnosideeff 0x200 // function has no side effects
#define F3badoparrow 0x400 // bad operator->()
Expand All @@ -677,6 +671,7 @@ typedef struct FUNC_S
#define Fmember 0x2000 // D member function with 'this'
#define Fnotailrecursion 0x4000 // no tail recursion optimizations
#define Ffakeeh 0x8000 // allocate space for NT EH context sym anyway
#define Fnothrow 0x10000 // function does not throw (even if not marked 'nothrow')
unsigned char Foper; // operator number (OPxxxx) if Foperator

Symbol *Fparsescope; // use this scope to parse friend functions
Expand Down Expand Up @@ -747,18 +742,9 @@ typedef struct BASECLASS
Classsym *BCbase; // base class Symbol
struct BASECLASS *BCnext; // next base class
targ_size_t BCoffset; // offset from start of derived class to this
#if VBTABLES
unsigned short BCvbtbloff; // for BCFvirtual, offset from start of
// vbtbl[] to entry for this virtual base.
// Valid in Sbase list
#else
targ_size_t memoffset; /* for BCFvirtual, offset from this to
pointer to virtual base class.
Valid in Sbase list
*/
Symbol *param; /* parameter for this Symbol (in */
/* Svirtbase list only) */
#endif
symlist_t BCpublics; // public members of base class (list is freeable)
list_t BCmptrlist; // (in Smptrbase only) this is the vtbl
// (NULL if not different from base class's vtbl
Expand Down Expand Up @@ -997,25 +983,21 @@ typedef struct STRUCT
Funcsym *Sctor; // constructor function

Funcsym *Sdtor; // basic destructor
#if VBTABLES
Funcsym *Sprimdtor; // primary destructor
Funcsym *Spriminv; // primary invariant
Funcsym *Sscaldeldtor; // scalar deleting destructor
#endif

Funcsym *Sinvariant; // basic invariant function

Symbol *Svptr; // Symbol of vptr
Symbol *Svtbl; // Symbol of vtbl[]
#if VBTABLES
Symbol *Svbptr; // Symbol of pointer to vbtbl[]
Symbol *Svbptr_parent; // base class for which Svbptr is a member.
// NULL if Svbptr is a member of this class
targ_size_t Svbptr_off; // offset of Svbptr member
Symbol *Svbtbl; // virtual base offset table
baseclass_t *Svbptrbase; // list of all base classes in canonical
// order that have their own vbtbl[]
#endif
Funcsym *Sopeq; // X& X::operator =(X&)
Funcsym *Sopeq2; // Sopeq, but no copy of virtual bases
Funcsym *Scpct; // copy constructor
Expand Down Expand Up @@ -1191,12 +1173,6 @@ struct Symbol
const char *prettyIdent; // the symbol identifer as the user sees it
#endif

#if ELFOBJ || MACHOBJ
long obj_si; // Symbol index of coff or elf symbol
unsigned long dwarf_off; // offset into .debug section
targ_size_t code_off; // rel. offset from start of block where var is initialized
targ_size_t last_off; // last offset using var
#endif
#if TARGET_OSX
targ_size_t Slocalgotoffset;
#endif
Expand Down Expand Up @@ -1297,12 +1273,7 @@ struct Symbol
}_SXR;
regm_t Sregsaved; // mask of registers not affected by this func

#if SOURCE_4SYMS
Srcpos Ssrcpos; // file position for definition
#endif

char Sident[SYM_PREDEF_SZ]; // identifier string (dynamic array)
// (the size is for static Symbols)
char Sident[1]; // identifier string (dynamic array)

int needThis(); // !=0 if symbol needs a 'this' pointer
bool Sisdead(bool anyiasm); // if variable is not referenced
Expand Down Expand Up @@ -1387,9 +1358,6 @@ struct PARAM
PARAM *Pnext; // next in list
unsigned Pflags;
#define PFexplicit 1 // this template argument was explicit, i.e. in < >
#if SOURCE_4PARAMS
Srcpos Psrcpos; // parameter source definition
#endif

PARAM *createTal(PARAM *); // create template-argument-list blank from
// template-parameter-list
Expand All @@ -1407,6 +1375,7 @@ struct PARAM

enum FL
{
// Change this, update debug.c too
FLunde,
FLconst, // numerical constant
FLoper, // operator node
Expand All @@ -1431,13 +1400,13 @@ enum FL
FLdtor, // destructed object
FLregsave, // ref to saved register on stack, int contains offset
FLasm, // (code) an ASM code
#if TX86

FLndp, // saved 8087 register
#endif
#if TARGET_SEGMENTED

// Segmented systems
FLfardata, // ref to far data segment
FLcsdata, // ref to code segment variable
#endif

FLlocalsize, // replaced with # of locals in the stack frame
FLtlsdata, // thread local storage
FLbprel, // ref to variable at fixed offset from frame pointer
Expand All @@ -1446,13 +1415,13 @@ enum FL
FLallocatmp, // temp for built-in alloca()
FLstack, // offset from ESP rather than EBP
FLdsymbol, // it's a Dsymbol
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
// Change this, update debug.c too

// Global Offset Table
FLgot, // global offset table entry outside this object file
FLgotoff, // global offset table entry inside this object file
//FLoncedata, // link once data
//FLoncecode, // link once code
#endif

FLfuncarg, // argument to upcoming function call

FLMAX
};

Expand Down
37 changes: 2 additions & 35 deletions src/backend/cdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
/* Macros defined by the compiler, not the code:
Compiler:
__SC__ Symantec compiler
__DMC__ Digital Mars compiler
_MSC_VER Microsoft compiler
__GNUC__ Gnu compiler
Expand Down Expand Up @@ -492,7 +491,6 @@ typedef targ_uns targ_size_t; /* size_t for the target machine */
#define THUNKS 1 /* use thunks for virtual functions */
#define SEPNEWDEL 1 // new/delete are not called within the ctor/dtor,
// they are separate
#define VBTABLES 1 // use Microsoft object model
#define UNICODE 1 // support Unicode (wchar_t is unsigned short)
#define DLCMSGS 0 // if 1, have all messages in a file
#define NEWMANGLE TARGET_WINDOS // use MS name mangling scheme
Expand Down Expand Up @@ -553,9 +551,6 @@ typedef targ_uns targ_size_t; /* size_t for the target machine */
#define UNKNOWN -1 /* unknown segment */
#define DGROUPIDX 1 /* group index of DGROUP */

#define KEEPBITFIELDS 0 /* 0 means code generator cannot handle bit fields, */
/* so replace them with shifts and masks */

#define REGMAX 29 // registers are numbered 0..10

typedef unsigned tym_t; // data type big enough for type masks
Expand All @@ -576,7 +571,6 @@ typedef int bool;
#define _far
#define __far
#define __cs
#define __ss
#endif

#if _WINDLL
Expand Down Expand Up @@ -680,8 +674,8 @@ struct Config
unsigned objfmt; // target object format
#define OBJ_OMF 1
#define OBJ_MSCOFF 2
#define OBJ_ELF 3
#define OBJ_MACH 4
#define OBJ_ELF 4
#define OBJ_MACH 8
unsigned exe; // target operating system
#define EX_DOSX 1 // DOSX 386 program
#define EX_ZPM 2 // ZPM 286 program
Expand Down Expand Up @@ -981,35 +975,8 @@ union eve
#define IDSYMBOL
#endif

#if SCPP
#define SYMBOLZERO 0,0,0,
#elif MARS
#define SYMBOLZERO 0,0,
#else
#define SYMBOLZERO
#endif

#if TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
#define UNIXFIELDS (unsigned)-1,(unsigned)-1,0,0,
#elif TARGET_OSX
#define UNIXFIELDS (unsigned)-1,(unsigned)-1,0,0,0,
#else
#define UNIXFIELDS
#endif

typedef unsigned SYMFLGS;
#if MARS
#define SYM_PREDEF_SZ 40
#else
#define SYM_PREDEF_SZ 22
#endif

#define SYMBOLY(fl,regsaved,name,flags) \
{IDSYMBOL \
(symbol *)0,(symbol *)0,(symbol *)0,(dt_t *)0,0,(type *)0,{0},\
SYMBOLZERO\
UNIXFIELDS\
SCextern,(fl),(flags),0,0,0,0,0,0,0,{0},(regsaved),{name}}

/**********************************
* Storage classes
Expand Down
3 changes: 1 addition & 2 deletions src/backend/cdeflnx.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#define M_UNIX 1
#define MEMMODELS 1
#if __GNUC__
#define __SC__ 0
//#define __DMC__ 0
#define _MSC_VER 0
#endif

Expand All @@ -29,7 +29,6 @@
#define __pascal
#define __far
#define _far
#define __ss
#define __cs

#if SCPP
Expand Down
16 changes: 8 additions & 8 deletions src/backend/cg87.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,26 +109,26 @@ STATIC code *getlvalue87(code *pcs,elem *e,regm_t keepmsk)
*/

code *ndp_fstp(code *c, int i, tym_t ty)
{ unsigned grex = I64 ? (REX_W << 16) : 0;
{
switch (tybasic(ty))
{
case TYfloat:
case TYifloat:
case TYcfloat:
c = genc1(c,0xD9,grex | modregrm(2,3,BPRM),FLndp,i); // FSTP m32real i[BP]
c = genc1(c,0xD9,modregrm(2,3,BPRM),FLndp,i); // FSTP m32real i[BP]
break;

case TYdouble:
case TYdouble_alias:
case TYidouble:
case TYcdouble:
c = genc1(c,0xDD,grex | modregrm(2,3,BPRM),FLndp,i); // FSTP m64real i[BP]
c = genc1(c,0xDD,modregrm(2,3,BPRM),FLndp,i); // FSTP m64real i[BP]
break;

case TYldouble:
case TYildouble:
case TYcldouble:
c = genc1(c,0xDB,grex | modregrm(2,7,BPRM),FLndp,i); // FSTP m80real i[BP]
c = genc1(c,0xDB,modregrm(2,7,BPRM),FLndp,i); // FSTP m80real i[BP]
break;

default:
Expand All @@ -138,26 +138,26 @@ code *ndp_fstp(code *c, int i, tym_t ty)
}

code *ndp_fld(code *c, int i, tym_t ty)
{ unsigned grex = I64 ? (REX_W << 16) : 0;
{
switch (tybasic(ty))
{
case TYfloat:
case TYifloat:
case TYcfloat:
c = genc1(c,0xD9,grex | modregrm(2,0,BPRM),FLndp,i);
c = genc1(c,0xD9,modregrm(2,0,BPRM),FLndp,i);
break;

case TYdouble:
case TYdouble_alias:
case TYidouble:
case TYcdouble:
c = genc1(c,0xDD,grex | modregrm(2,0,BPRM),FLndp,i);
c = genc1(c,0xDD,modregrm(2,0,BPRM),FLndp,i);
break;

case TYldouble:
case TYildouble:
case TYcldouble:
c = genc1(c,0xDB,grex | modregrm(2,5,BPRM),FLndp,i); // FLD m80real i[BP]
c = genc1(c,0xDB,modregrm(2,5,BPRM),FLndp,i); // FLD m80real i[BP]
break;

default:
Expand Down
178 changes: 118 additions & 60 deletions src/backend/cgcod.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,15 @@ targ_size_t spoff;
targ_size_t Foff; // BP offset of floating register
targ_size_t CSoff; // offset of common sub expressions
targ_size_t NDPoff; // offset of saved 8087 registers
targ_size_t pushoff; // offset of saved registers
bool pushoffuse; // using pushoff
int BPoff; // offset from BP
int EBPtoESP; // add to EBP offset to get ESP offset
int AllocaOff; // offset of alloca temporary
LocalSection Para; // section of function parameters
LocalSection Auto; // section of automatics and registers
LocalSection Fast; // section of fastpar
LocalSection EEStack; // offset of SCstack variables from ESP
LocalSection Alloca; // data for alloca() temporary

REGSAVE regsave;

Expand All @@ -79,7 +81,6 @@ bool anyiasm; // !=0 if any inline assembler
char calledafunc; // !=0 if we called a function
char needframe; // if TRUE, then we will need the frame
// pointer (BP for the 8088)
char usedalloca; // if TRUE, then alloca() was called
char gotref; // !=0 if the GOTsym was referenced
unsigned usednteh; // if !=0, then used NT exception handling

Expand Down Expand Up @@ -110,8 +111,8 @@ regm_t allregs; // ALLREGS optionally including mBP

int dfoidx; /* which block we are in */
struct CSE *csextab = NULL; /* CSE table (allocated for each function) */
unsigned cstop; /* # of entries in CSE table (csextab[]) */
unsigned csmax; /* amount of space in csextab[] */
size_t cstop; // # of entries in CSE table (csextab[])
size_t csmax; // amount of space in csextab[]

targ_size_t funcoffset; // offset of start of function
targ_size_t prolog_allocoffset; // offset past adj of stack allocation
Expand Down Expand Up @@ -146,6 +147,8 @@ void codgen()
cod3_initregs();
allregs = ALLREGS;
pass = PASSinit;
Alloca.init();
anyiasm = 0;

tryagain:
#ifdef DEBUG
Expand All @@ -157,16 +160,17 @@ void codgen()

// if no parameters, assume we don't need a stack frame
needframe = 0;
usedalloca = 0;
gotref = 0;
stackchanged = 0;
stackpush = 0;
refparam = 0;
anyiasm = 0;
calledafunc = 0;
cgstate.stackclean = 1;
retsym = NULL;

cgstate.stackclean = 1;
cgstate.funcarg.init();
cgstate.funcargtos = ~0;

regsave.reset();
#if TX86
memset(_8087elems,0,sizeof(_8087elems));
Expand All @@ -186,6 +190,9 @@ void codgen()
}
#endif

// Set on a trial basis, turning it off if anything might throw
funcsym_p->Sfunc->Fflags3 |= Fnothrow;

floatreg = FALSE;
#if TX86
assert(stackused == 0); /* nobody in 8087 stack */
Expand Down Expand Up @@ -383,11 +390,13 @@ void codgen()
#endif

// Compute starting offset for switch tables
#if ELFOBJ || MACHOBJ
targ_size_t swoffset = (config.flags & CFGromable) ? coffset : CDoffset;
#else
targ_size_t swoffset = (config.flags & CFGromable) ? coffset : Doffset;
#endif
targ_size_t swoffset;
if (config.flags & CFGromable)
swoffset = coffset;
else if (config.objfmt == OBJ_ELF || config.objfmt == OBJ_MACH)
swoffset = CDoffset;
else
swoffset = Doffset;
swoffset = align(0,swoffset);

// Emit the generated code
Expand Down Expand Up @@ -627,7 +636,37 @@ code *prolog()
tym_t tyf = funcsym_p->ty();
tym_t tym = tybasic(tyf);
unsigned farfunc = tyfarfunc(tym);
if (config.flags & CFGalwaysframe || funcsym_p->Sfunc->Fflags3 & Ffakeeh)

// Special Intel 64 bit ABI prolog setup for variadic functions
symbol *sv64 = NULL; // set to __va_argsave
if (I64 && variadic(funcsym_p->Stype))
{
/* The Intel 64 bit ABI scheme.
* abi_sysV_amd64.pdf
* Load arguments passed in registers into the varargs save area
* so they can be accessed by va_arg().
*/
/* Look for __va_argsave
*/
for (SYMIDX si = 0; si < globsym.top; si++)
{ symbol *s = globsym.tab[si];
if (s->Sident[0] == '_' && strcmp(s->Sident, "__va_argsave") == 0)
{
if (!(s->Sflags & SFLdead))
sv64 = s;
break;
}
}
}

if (config.flags & CFGalwaysframe ||
funcsym_p->Sfunc->Fflags3 & Ffakeeh ||
/* The exception stack unwinding mechanism relies on the EBP chain being intact,
* so need frame if function can possibly throw
*/
!(config.flags2 & CFG2seh) && !(funcsym_p->Sfunc->Fflags3 & Fnothrow) ||
sv64
)
needframe = 1;

Lagain:
Expand All @@ -649,7 +688,7 @@ code *prolog()
* Auto.size autos and regs
* regsave.off any saved registers
* Foff floating register
* AllocaOff alloca temporary
* Alloca.size alloca temporary
* CSoff common subs
* NDPoff any 8087 saved registers
* monitor context record
Expand All @@ -675,9 +714,11 @@ code *prolog()
#if NTEXCEPTIONS == 2
Fast.size -= nteh_contextsym_size();
#if MARS
#if TARGET_WINDOS
if (funcsym_p->Sfunc->Fflags3 & Ffakeeh && nteh_contextsym_size() == 0)
Fast.size -= 5 * 4;
#endif
#endif
#endif

/* Despite what the comment above says, aligning Fast section to size greater
Expand Down Expand Up @@ -716,34 +757,65 @@ code *prolog()

regsave.off = alignsection(Auto.size - regsave.top, regsave.alignment, bias);

unsigned floatregsize = floatreg ? (config.fpxmmregs || I32 ? 16 : DOUBLESIZE) : 0;
Foff = alignsection(regsave.off - floatregsize, STACKALIGN, bias);
if (floatreg)
{
unsigned floatregsize = config.fpxmmregs || I32 ? 16 : DOUBLESIZE;
Foff = alignsection(regsave.off - floatregsize, STACKALIGN, bias);
}
else
Foff = regsave.off;

assert(usedalloca != 1);
AllocaOff = alignsection(usedalloca ? (Foff - REGSIZE) : Foff, REGSIZE, bias);
Alloca.alignment = REGSIZE;
Alloca.offset = alignsection(Foff - Alloca.size, Alloca.alignment, bias);

CSoff = alignsection(AllocaOff - cstop * REGSIZE, REGSIZE, bias);
CSoff = alignsection(Alloca.offset - cstop * REGSIZE, REGSIZE, bias);

#if TX86
NDPoff = alignsection(CSoff - NDP::savetop * NDPSAVESIZE, REGSIZE, bias);
#else
NDPoff = CSoff;
#endif

regm_t topush = fregsaved & ~mfuncreg; // mask of registers that need saving
pushoffuse = false;
pushoff = NDPoff;
if (config.flags4 & CFG4speed && (I32 || I64))
{
/* Instead of pushing the registers onto the stack one by one,
* allocate space in the stack frame and copy/restore them there.
*/
int xmmtopush = numbitsset(topush & XMMREGS); // XMM regs take 16 bytes
int gptopush = numbitsset(topush) - xmmtopush; // general purpose registers to save
if (NDPoff || xmmtopush || cgstate.funcarg.size)
{
pushoff = alignsection(pushoff - (gptopush * REGSIZE + xmmtopush * 16),
xmmtopush ? STACKALIGN : REGSIZE, bias);
pushoffuse = true; // tell others we're using this strategy
}
}

//printf("Fast.size = x%x, Auto.size = x%x\n", (int)Fast.size, (int)Auto.size);

localsize = -NDPoff;
cgstate.funcarg.alignment = STACKALIGN;
cgstate.funcarg.offset = alignsection(pushoff - cgstate.funcarg.size, cgstate.funcarg.alignment, bias);

localsize = -cgstate.funcarg.offset;

regm_t topush = fregsaved & ~mfuncreg; // mask of registers that need saving
int npush = numbitsset(topush); // number of registers that need saving
npush += numbitsset(topush & XMMREGS); // XMM regs take 16 bytes, so count them twice
//printf("Alloca.offset = x%llx, cstop = x%llx, CSoff = x%llx, NDPoff = x%llx, localsize = x%llx\n",
//(long long)Alloca.offset, (long long)cstop, (long long)CSoff, (long long)NDPoff, (long long)localsize);
assert((targ_ptrdiff_t)localsize >= 0);

// Keep the stack aligned by 8 for any subsequent function calls
if (!I16 && calledafunc &&
(STACKALIGN == 16 || config.flags4 & CFG4stackalign))
{
int npush = numbitsset(topush); // number of registers that need saving
npush += numbitsset(topush & XMMREGS); // XMM regs take 16 bytes, so count them twice
if (pushoffuse)
npush = 0;

//printf("npush = %d Para.size = x%x needframe = %d localsize = x%x\n",
// npush, Para.size, needframe, localsize);
//npush, Para.size, needframe, localsize);

int sz = Para.size + (needframe ? 0 : -REGSIZE) + localsize + npush * REGSIZE;
if (STACKALIGN == 16)
Expand All @@ -754,6 +826,7 @@ code *prolog()
else if (sz & 4)
localsize += 4;
}
cgstate.funcarg.offset = -localsize;

//printf("Foff x%02x Auto.size x%02x NDPoff x%02x CSoff x%02x Para.size x%02x localsize x%02x\n",
//(int)Foff,(int)Auto.size,(int)NDPoff,(int)CSoff,(int)Para.size,(int)localsize);
Expand Down Expand Up @@ -788,7 +861,7 @@ code *prolog()
xlocalsize >= 0x1000 ||
(usednteh & ~NTEHjmonitor) ||
anyiasm ||
usedalloca
Alloca.size
)
needframe = 1;
}
Expand Down Expand Up @@ -822,28 +895,28 @@ code *prolog()
if (config.flags & CFGstack) // if stack overflow check
{
cstackadj = prolog_frameadj(tyf, xlocalsize, enter, &pushalloc);
if (usedalloca)
if (Alloca.size)
cstackadj = cat(cstackadj, prolog_setupalloca());
}
else if (needframe) /* if variables or parameters */
{
if (xlocalsize) /* if any stack offset */
{
cstackadj = prolog_frameadj(tyf, xlocalsize, enter, &pushalloc);
if (usedalloca)
if (Alloca.size)
cstackadj = cat(cstackadj, prolog_setupalloca());
}
else
assert(usedalloca == 0);
assert(Alloca.size == 0);
}
else if (xlocalsize)
{
assert(I32);
assert(I32 || I64);
cstackadj = prolog_frameadj2(tyf, xlocalsize, &pushalloc);
BPoff += REGSIZE;
}
else
assert((localsize | usedalloca) == 0 || (usednteh & NTEHjmonitor));
assert((localsize | Alloca.size) == 0 || (usednteh & NTEHjmonitor));
EBPtoESP += xlocalsize;
c = cat(c, cstackadj);
}
Expand Down Expand Up @@ -931,28 +1004,8 @@ code *prolog()
// the register!
c = cat(c, prolog_loadparams(tyf, pushalloc, &namedargs));

// Special Intel 64 bit ABI prolog setup for variadic functions
if (I64 && variadic(funcsym_p->Stype))
{
/* The Intel 64 bit ABI scheme.
* abi_sysV_amd64.pdf
* Load arguments passed in registers into the varargs save area
* so they can be accessed by va_arg().
*/
/* Look for __va_argsave
*/
symbol *sv = NULL;
for (SYMIDX si = 0; si < globsym.top; si++)
{ symbol *s = globsym.tab[si];
if (s->Sident[0] == '_' && strcmp(s->Sident, "__va_argsave") == 0)
{ sv = s;
break;
}
}

if (sv && !(sv->Sflags & SFLdead))
c = cat(c, prolog_genvarargs(sv, &namedargs));
}
if (sv64)
c = cat(c, prolog_genvarargs(sv64, &namedargs));

/* Alignment checks
*/
Expand Down Expand Up @@ -1047,6 +1100,10 @@ void stackoffsets(int flags)
switch (s->Sclass)
{
case SCfastpar:
if (!(funcsym_p->Sfunc->Fflags3 & Ffakeeh))
continue; // don't need consistent stack frame
break;

case SCshadowreg:
case SCparameter:
break; // have to allocate space for parameters
Expand Down Expand Up @@ -1610,13 +1667,13 @@ void freenode(elem *e)
if (e->Ecomsub--) return; /* usage count */
if (e->Ecount) /* if it was a CSE */
{
for (unsigned i = 0; i < arraysize(regcon.cse.value); i++)
for (size_t i = 0; i < arraysize(regcon.cse.value); i++)
{ if (regcon.cse.value[i] == e) /* if a register is holding it */
{ regcon.cse.mval &= ~mask[i];
regcon.cse.mops &= ~mask[i]; /* free masks */
}
}
for (unsigned i = 0; i < cstop; i++)
for (size_t i = 0; i < cstop; i++)
{ if (csextab[i].e == e)
csextab[i].e = NULL;
}
Expand Down Expand Up @@ -1957,7 +2014,7 @@ STATIC code * cse_save(regm_t ms)
if (regm & ms)
{
elem *e = regcon.cse.value[findreg(regm)];
for (unsigned i = 0; i < csmax; i++)
for (size_t i = 0; i < csmax; i++)
{
if (csextab[i].e == e)
{
Expand All @@ -1980,10 +2037,11 @@ STATIC code * cse_save(regm_t ms)
}
}

for (unsigned i = cstop; ms; i++)
for (size_t i = cstop; ms; i++)
{
if (i >= csmax) /* array overflow */
{ unsigned cseinc;
{
size_t cseinc;

#ifdef DEBUG
cseinc = 8; /* flush out reallocation bugs */
Expand Down Expand Up @@ -2221,7 +2279,7 @@ STATIC code * comsub(elem *e,regm_t *pretregs)

/* create mask of what's in csextab[] */
csemask = 0;
for (unsigned i = 0; i < cstop; i++)
for (size_t i = 0; i < cstop; i++)
{ if (csextab[i].e)
elem_debug(csextab[i].e);
if (csextab[i].e == e)
Expand Down Expand Up @@ -2260,7 +2318,7 @@ if (regcon.cse.mval & 1) elem_print(regcon.cse.value[0]);

if (!EOP(e)) /* if not op or func */
goto reload; /* reload data */
for (unsigned i = cstop; i--;) /* look through saved comsubs */
for (size_t i = cstop; i--;) /* look through saved comsubs */
if (csextab[i].e == e) /* found it */
{ regm_t retregs;

Expand Down Expand Up @@ -2421,7 +2479,7 @@ if (regcon.cse.mval & 1) elem_print(regcon.cse.value[0]);

STATIC code * loadcse(elem *e,unsigned reg,regm_t regm)
{
for (unsigned i = cstop; i--;)
for (size_t i = cstop; i--;)
{
//printf("csextab[%d] = %p, regm = %s\n", i, csextab[i].e, regm_str(csextab[i].regm));
if (csextab[i].e == e && csextab[i].regm & regm)
Expand Down
16 changes: 4 additions & 12 deletions src/backend/cgcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,8 @@ STATIC void ecom(elem **pe)
case OPnegass:
if (EOP(e->E1)) /* if lvalue is an operator */
{
#ifdef DEBUG
if (e->E1->Eoper != OPind)
elem_print(e);
#endif
assert(e->E1->Eoper == OPind);
ecom(&(e->E1->E1));
}
Expand All @@ -235,6 +233,7 @@ STATIC void ecom(elem **pe)
case OPbtc:
case OPbts:
case OPbtr:
case OPcmpxchg:
ecom(&e->E1);
ecom(&e->E2);
touchfunc(0); // indirect assignment
Expand Down Expand Up @@ -324,9 +323,8 @@ STATIC void ecom(elem **pe)
touchfunc(0);
return;
default: /* other operators */
#ifdef DEBUG
if (!EBIN(e)) WROP(e->Eoper);
#endif
if (!EBIN(e))
WROP(e->Eoper);
assert(EBIN(e));
case OPadd:
case OPmin:
Expand All @@ -348,10 +346,8 @@ STATIC void ecom(elem **pe)
case OPstring:
case OPaddr:
case OPbit:
#ifdef DEBUG
WROP(e->Eoper);
elem_print(e);
#endif
assert(0); /* optelem() should have removed these */
/* NOTREACHED */

Expand All @@ -371,7 +367,7 @@ STATIC void ecom(elem **pe)
case OPd_s64: case OPs64_d: case OPd_u64: case OPu64_d:
case OPstrctor: case OPu16_d: case OPd_u16:
case OParrow:
case OPvoid: case OPnullcheck:
case OPvoid:
case OPbsf: case OPbsr: case OPbswap: case OPpopcnt: case OPvector:
case OPld_u64:
#if TX86
Expand Down Expand Up @@ -530,10 +526,8 @@ STATIC void touchlvalue(elem *e)
hcstab[i].Helem = NULL;
}

#ifdef DEBUG
if (!(e->Eoper == OPvar || e->Eoper == OPrelconst))
elem_print(e);
#endif
assert(e->Eoper == OPvar || e->Eoper == OPrelconst);
switch (e->EV.sp.Vsym->Sclass)
{
Expand Down Expand Up @@ -561,10 +555,8 @@ STATIC void touchlvalue(elem *e)
touchstar();
break;
default:
#ifdef DEBUG
elem_print(e);
symbol_print(e->EV.sp.Vsym);
#endif
assert(0);
}
}
Expand Down
54 changes: 22 additions & 32 deletions src/backend/cgcv.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (C) 1984-1998 by Symantec
// Copyright (C) 2000-2013 by Digital Mars
// Copyright (C) 2000-2015 by Digital Mars
// All Rights Reserved
// http://www.digitalmars.com
// Written by Walter Bright
Expand All @@ -17,14 +17,6 @@
#include <time.h>
#include <stdlib.h>

#if _WIN32 || __linux__
#include <malloc.h>
#endif

#if __sun
#include <alloca.h>
#endif

#include "cc.h"
#include "type.h"
#include "code.h"
Expand Down Expand Up @@ -59,12 +51,6 @@ static unsigned debtyphash[DEBTYPHASHDIM];
*/
#define CVIDMAX (0xFF0-20) // the -20 is picked by trial and error

#if 0
#define DBG(a) a
#else
#define DBG(a)
#endif

#define LOCATsegrel 0xC000

/* Unfortunately, the fixup stuff is different for EASY OMF and Microsoft */
Expand Down Expand Up @@ -426,13 +412,11 @@ void cv_init()
{
dttab4[TYptr] = 0x600;
dttab4[TYnptr] = 0x600;
dttab4[TYjhandle] = 0x600;
}
else
{
dttab4[TYptr] = 0x400;
dttab4[TYnptr] = 0x400;
dttab4[TYjhandle] = 0x400;
}
#if TARGET_SEGMENTED
dttab4[TYsptr] = 0x400;
Expand Down Expand Up @@ -534,17 +518,19 @@ void cv_init()
// Put out S_TDBNAME record
if (config.fulltypes == CVTDB)
{
unsigned char *ds;
size_t len;
unsigned char buf[50];

pstate.STtdbtimestamp = tdb_gettimestamp();
len = cv_stringbytes(ftdbname);
ds = (unsigned char *) alloca(8 + len);
size_t len = cv_stringbytes(ftdbname);
unsigned char *ds = (8 + len <= sizeof(buf)) ? buf : (unsigned char *) malloc(8 + len);
assert(ds);
TOWORD(ds,6 + len);
TOWORD(ds + 2,S_TDBNAME);
TOLONG(ds + 4,pstate.STtdbtimestamp);
cv_namestring(ds + 8,ftdbname);
objmod->write_bytes(SegData[DEBSYM],8 + len,ds);
if (ds != buf)
free(ds);
}
#endif
}
Expand Down Expand Up @@ -739,9 +725,7 @@ STATIC int cv4_methodlist(symbol *sf,int *pcount)
case 0:
break;
default:
#ifdef DEBUG
symbol_print(s);
#endif
assert(0);
}
TOIDX(p,attribute);
Expand Down Expand Up @@ -987,7 +971,7 @@ idx_t cv4_struct(Classsym *s,int flags)
}
break;
default:
#if DEBUG && SCPP
#if SCPP
symbol_print(s);
#endif
assert(0);
Expand Down Expand Up @@ -2228,7 +2212,8 @@ STATIC void cv4_outsym(symbol *s)
unsigned u;
tym_t tym;
const char *id;
unsigned char __ss *debsym;
unsigned char *debsym = NULL;
unsigned char buf[64];

//dbg_printf("cv4_outsym(%s)\n",s->Sident);
symbol_debug(s);
Expand Down Expand Up @@ -2265,7 +2250,8 @@ STATIC void cv4_outsym(symbol *s)

// Length of record
length = 2 + 2 + 4 * 3 + intsize * 4 + 2 + cgcv.sz_idx + 1;
debsym = (unsigned char __ss *) alloca(length + len);
debsym = (length + len <= sizeof(buf)) ? buf : (unsigned char *) malloc(length + len);
assert(debsym);
memset(debsym,0,length + len);

// Symbol type
Expand Down Expand Up @@ -2340,7 +2326,8 @@ STATIC void cv4_outsym(symbol *s)
id = prettyident(s);
#endif
len = strlen(id);
debsym = (unsigned char __ss *) alloca(39 + IDOHD + len);
debsym = (39 + IDOHD + len <= sizeof(buf)) ? buf : (unsigned char *) malloc(39 + IDOHD + len);
assert(debsym);
switch (s->Sclass)
{
case SCparameter:
Expand Down Expand Up @@ -2403,7 +2390,7 @@ STATIC void cv4_outsym(symbol *s)
// Common blocks have a non-zero Sxtrnnum and an UNKNOWN seg
if (!(s->Sxtrnnum && s->Sseg == UNKNOWN)) // if it's not really a common block
{
return;
goto Lret;
}
/* FALL-THROUGH */
case SCglobal:
Expand Down Expand Up @@ -2474,7 +2461,7 @@ STATIC void cv4_outsym(symbol *s)
objmod->write_long(DEBSYM,offset + fixoff,s->Soffset,
cgcv.LCFDpointer + fd,idx1,idx2);
}
return;
goto Lret;

#if 1
case SCtypedef:
Expand All @@ -2483,13 +2470,13 @@ STATIC void cv4_outsym(symbol *s)

case SCstruct:
if (s->Sstruct->Sflags & STRnotagname)
return;
goto Lret;
goto L4;

case SCenum:
#if SCPP
if (CPP && s->Senum->SEflags & SENnotagname)
return;
goto Lret;
#endif
L4:
// Output a 'user-defined type' for the tag name
Expand All @@ -2514,11 +2501,14 @@ STATIC void cv4_outsym(symbol *s)
break;
#endif
default:
return;
goto Lret;
}
assert(length <= 40 + len);
objmod->write_bytes(SegData[DEBSYM],length,debsym);
}
Lret:
if (debsym != buf)
free(debsym);
}

/******************************************
Expand Down
189 changes: 86 additions & 103 deletions src/backend/cgelem.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ static char __file__[] = __FILE__; /* for tassert.h */
extern void error(const char *filename, unsigned linnum, unsigned charnum, const char *format, ...);

STATIC elem * optelem(elem *,goal_t);
STATIC elem * elarray(elem *e);
STATIC elem * eldiv(elem *, goal_t goal);

extern elem * evalu8(elem *, goal_t goal);
Expand Down Expand Up @@ -785,10 +784,8 @@ STATIC elem * eladd(elem *e, goal_t goal)
e2 = e->E2;
if (e2->Eoper == OPconst)
{
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
if (e1->Eoper == OPrelconst && e1->EV.sp.Vsym->Sfl == FLgot)
goto ret;
#endif
if (e1->Eoper == OPrelconst /* if (&v) + c */
|| e1->Eoper == OPstring
)
Expand All @@ -801,10 +798,8 @@ STATIC elem * eladd(elem *e, goal_t goal)
}
else if (e1->Eoper == OPconst)
{
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
if (e2->Eoper == OPrelconst && e2->EV.sp.Vsym->Sfl == FLgot)
goto ret;
#endif
if (e2->Eoper == OPrelconst /* if c + (&v) */
|| e2->Eoper == OPstring
)
Expand Down Expand Up @@ -1101,7 +1096,7 @@ STATIC elem * elmin(elem *e, goal_t goal)
/* for floating or far or huge pointers! */
if (e1->Eoper == OPadd && e2->Eoper == OPadd &&
cnst(e1->E2) && cnst(e2->E2) &&
(tyintegral(tym) || tybasic(tym) == TYjhandle || tybasic(tym) == TYnptr
(tyintegral(tym) || tybasic(tym) == TYnptr
#if TARGET_SEGMENTED
|| tybasic(tym) == TYsptr
#endif
Expand Down Expand Up @@ -1130,14 +1125,20 @@ STATIC elem * elmin(elem *e, goal_t goal)
#if TX86 && !(MARS)
if (tybasic(e2->Ety) == TYhptr && tybasic(e->E1->Ety) == TYhptr)
{ // Convert to _aNahdiff(e1,e2)
static symbol hdiff = SYMBOLY(FLfunc,mBX|mCX|mSI|mDI|mBP|mES,"_aNahdiff",0);

if (LARGECODE)
hdiff.Sident[2] = 'F';
hdiff.Stype = tsclib;
static symbol *hdiff;
if (!hdiff)
{
symbol *s = symbol_calloc(LARGECODE ? "_aFahdiff" : "_aNahdiff");
s->Stype = tsclib;
s->Sclass = SCextern;
s->Sfl = FLfunc;
s->Ssymnum = 0;
s->Sregsaved = mBX|mCX|mSI|mDI|mBP|mES;
hdiff = s;
}
e->Eoper = OPcall;
e->E2 = el_bin(OPparam,TYint,e2,e->E1);
e->E1 = el_var(&hdiff);
e->E1 = el_var(hdiff);
return e;
}
#endif
Expand Down Expand Up @@ -3307,7 +3308,6 @@ STATIC elem * eleq(elem *e, goal_t goal)
unsigned t,w,b;
unsigned sz;
elem *l,*l2,*r,*r2,*e1,*eres;
tym_t tyl;

#if SCPP
goal_t wantres = goal;
Expand Down Expand Up @@ -3336,7 +3336,7 @@ STATIC elem * eleq(elem *e, goal_t goal)
* so that garbage doesn't creep into the extra 2 bytes
* and throw off compares.
*/
tyl = tybasic(e1->Ety);
tym_t tyl = tybasic(e1->Ety);
if (e1->Eoper == OPvar && (tyl == TYldouble || tyl == TYildouble || tyl == TYcldouble))
{
#if 1
Expand Down Expand Up @@ -3520,8 +3520,68 @@ STATIC elem * eleq(elem *e, goal_t goal)
e2->E2 = es;
e2->Eoper = OPxor;
return optelem(e,GOALvalue);

L8: ;
}

// Replace (a=(r1 pair r2)) with (a1=r1), (a2=r2)
if (tysize(e1->Ety) == 2 * REGSIZE &&
e1->Eoper == OPvar &&
(e2->Eoper == OPpair || e2->Eoper == OPrpair) &&
goal == GOALnone
)
{
tym_t ty = (REGSIZE == 8) ? TYllong : TYint;
if (tyfloating(e1->Ety) && REGSIZE >= 4)
ty = (REGSIZE == 8) ? TYdouble : TYfloat;
ty |= e1->Ety & ~mTYbasic;
e2->Ety = ty;
e->Ety = ty;
e1->Ety = ty;
elem *eb = el_copytree(e1);
eb->EV.sp.Voffset += REGSIZE;

if (e2->Eoper == OPpair)
{
e->E2 = e2->E1;
eb = el_bin(OPeq,ty,eb,e2->E2);
e2->E1 = eb;
e2->E2 = e;
}
else
{
e->E2 = e2->E2;
eb = el_bin(OPeq,ty,eb,e2->E1);
e2->E1 = eb;
e2->E2 = e;
}

e2->Eoper = OPcomma;
return optelem(e2,goal);
}

// Replace (a=b) with (a1=b1),(a2=b2)
if (tysize(e1->Ety) == 2 * REGSIZE &&
e1->Eoper == OPvar &&
e2->Eoper == OPvar &&
goal == GOALnone
)
{
tym_t ty = (REGSIZE == 8) ? TYllong : TYint;
if (tyfloating(e1->Ety) && REGSIZE >= 4)
ty = (REGSIZE == 8) ? TYdouble : TYfloat;
ty |= e1->Ety & ~mTYbasic;
e2->Ety = ty;
e->Ety = ty;
e1->Ety = ty;

elem *eb = el_copytree(e);
eb->E1->EV.sp.Voffset += REGSIZE;
eb->E2->EV.sp.Voffset += REGSIZE;

e = el_bin(OPcomma,ty,e,eb);
return optelem(e,goal);
}
L8: ;
}

if (e1->Eoper == OPcomma)
Expand All @@ -3537,7 +3597,7 @@ STATIC elem * eleq(elem *e, goal_t goal)
t = e->Ety;
l = e1->E1; /* lvalue */
r = e->E2;
tyl = l->Ety;
tym_t tyl = l->Ety;
sz = tysize(tyl) * 8;
w = (e1->E2->EV.Vuns >> 8); /* width in bits of field */
m = ((targ_ullong)1 << w) - 1; // mask w bits wide
Expand Down Expand Up @@ -4071,6 +4131,7 @@ STATIC elem * elcmp(elem *e, goal_t goal)

STATIC elem * elbool(elem *e, goal_t goal)
{
//printf("elbool()\n");
if (OTlogical(e->E1->Eoper) ||
// bool bool => bool
(tybasic(e->E1->Ety) == TYbool && tysize(e->Ety) == 1)
Expand Down Expand Up @@ -4240,11 +4301,10 @@ STATIC elem * elvptrfptr(elem *e, goal_t goal)
*/

STATIC elem * ellngsht(elem *e, goal_t goal)
{ elem *e1;
tym_t ty;

ty = e->Ety;
e1 = e->E1;
{
//printf("ellngsht()\n");
tym_t ty = e->Ety;
elem *e1 = e->E1;
switch (e1->Eoper)
{ case OPs16_32:
case OPu16_32:
Expand Down Expand Up @@ -4288,6 +4348,10 @@ STATIC elem * ellngsht(elem *e, goal_t goal)
break;
#endif

case OPbtst:
e = el_selecte1(e);
break;

default: /* operator */
case_default:
/* Attempt to replace (lngsht)(a op b) with */
Expand Down Expand Up @@ -4760,23 +4824,6 @@ STATIC elem * elinfo(elem *e, goal_t goal)
return e;
}

/********************************************
*/

STATIC elem * elhstring(elem *e, goal_t goal)
{
return e;
}

/********************************************
*/

STATIC elem * elnullcheck(elem *e, goal_t goal)
{
return e;
}


/********************************************
*/

Expand All @@ -4785,54 +4832,6 @@ STATIC elem * elclassinit(elem *e, goal_t goal)
return e;
}

/********************************************
*/

STATIC elem * elnewarray(elem *e, goal_t goal)
{
return e;
}

/********************************************
*/

STATIC elem * elmultinewarray(elem *e, goal_t goal)
{
return e;
}

/********************************************
*/

STATIC elem * elinstanceof(elem *e, goal_t goal)
{
return e;
}

/********************************************
*/

STATIC elem * elfinalinstanceof(elem *e, goal_t goal)
{
return e;
}

/********************************************
*/

STATIC elem * elcheckcast(elem *e, goal_t goal)
{
return e;
}

/********************************************
*/

STATIC elem * elarraylength(elem *e, goal_t goal)
{
return e;
}

/********************************************
*/

Expand Down Expand Up @@ -4907,22 +4906,6 @@ STATIC elem * elvalist(elem *e, goal_t goal)
}
#endif

/********************************************
*/

STATIC elem * elarray(elem *e, goal_t goal)
{
return e;
}

/********************************************
*/

STATIC elem * elfield(elem *e, goal_t goal)
{
return e;
}

/******************************************
* OPparam
*/
Expand Down Expand Up @@ -5354,7 +5337,7 @@ STATIC elem * optelem(elem *e, goal_t goal)
}
else /* unary operator */
{
assert(!e->E2 || op == OPinfo || op == OParraylength || op == OPddtor);
assert(!e->E2 || op == OPinfo || op == OPddtor);
if (!goal && !OTsideff(op) && !(e->Ety & mTYvolatile))
{
tym_t tym = e->E1->Ety;
Expand Down
4 changes: 2 additions & 2 deletions src/backend/cgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ code *setOpcode(code *c, code *cs, unsigned op)
* Concatenate two code lists together. Return pointer to result.
*/

#if TX86 && __INTSIZE == 4 && __SC__
#if TX86 && __INTSIZE == 4 && __DMC__
__declspec(naked) code * __pascal cat(code *c1,code *c2)
{
_asm
Expand Down Expand Up @@ -173,7 +173,7 @@ code *gen(code *c,code *cs)
#if TX86
assert(I64 || cs->Irex == 0);
#endif
code* ce = code_calloc();
code* ce = code_malloc();
*ce = *cs;
//printf("ce = %p %02x\n", ce, ce->Iop);
ccheck(ce);
Expand Down
13 changes: 8 additions & 5 deletions src/backend/cgobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ struct Loc
void error(Loc loc, const char *format, ...);
#endif

#if OMFOBJ
#if TARGET_WINDOS

static char __file__[] = __FILE__; // for tassert.h
#include "tassert.h"
Expand Down Expand Up @@ -1130,13 +1130,16 @@ void Obj::dosseg()

STATIC void obj_comment(unsigned char x, const char *string, size_t len)
{
char __ss *library;
char buf[128];

library = (char __ss *) alloca(2 + len);
char *library = (2 + len <= sizeof(buf)) ? buf : (char *) malloc(2 + len);
assert(library);
library[0] = 0;
library[1] = x;
memcpy(library + 2,string,len);
objrecord(COMENT,library,len + 2);
if (library != buf)
free(library);
}

/*******************************
Expand Down Expand Up @@ -1862,7 +1865,7 @@ int Obj::comdatsize(Symbol *s, targ_size_t symsize)
int Obj::comdat(Symbol *s)
{ char lnames[IDMAX+IDOHD+1]; // +1 to allow room for strcpy() terminating 0
char cextdef[2+2];
char __ss *p;
char *p;
size_t lnamesize;
unsigned ti;
int isfunc;
Expand Down Expand Up @@ -2625,7 +2628,7 @@ void Obj::lidata(int seg,targ_size_t offset,targ_size_t count)
unsigned reclen;
static char zero[20];
char data[20];
char __ss *di;
char *di;

//printf("Obj::lidata(seg = %d, offset = x%x, count = %d)\n", seg, offset, count);

Expand Down
Loading