diff -uNr dmd-0.102/src/dmd/aggregate.h gdc-0.8/d/dmd/aggregate.h --- dmd-0.102/src/dmd/aggregate.h 2004-06-07 13:35:12.000000000 +0200 +++ gdc-0.8/d/dmd/aggregate.h 2004-10-15 01:21:22.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, October 2004 +*/ + #ifndef DMD_AGGREGATE_H #define DMD_AGGREGATE_H @@ -46,6 +52,10 @@ InvariantDeclaration *inv; // invariant NewDeclaration *aggNew; // allocator DeleteDeclaration *aggDelete; // deallocator +#ifdef IN_GCC + + Array methods; // flat list of all methods for debug information +#endif AggregateDeclaration(Loc loc, Identifier *id); diff -uNr dmd-0.102/src/dmd/array.c gdc-0.8/d/dmd/array.c --- dmd-0.102/src/dmd/array.c 2003-03-05 19:57:50.000000000 +0100 +++ gdc-0.8/d/dmd/array.c 2004-10-02 19:19:31.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #include #include #include @@ -21,7 +27,7 @@ #include #endif -#if linux +#ifndef _WIN32 #include #include #include diff -uNr dmd-0.102/src/dmd/cast.c gdc-0.8/d/dmd/cast.c --- dmd-0.102/src/dmd/cast.c 2004-08-28 17:31:04.000000000 +0200 +++ gdc-0.8/d/dmd/cast.c 2004-10-02 19:19:31.000000000 +0200 @@ -7,12 +7,18 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #include #include #if _WIN32 #include "mem.h" -#elif linux +#else #include "../root/mem.h" #endif diff -uNr dmd-0.102/src/dmd/constfold.c gdc-0.8/d/dmd/constfold.c --- dmd-0.102/src/dmd/constfold.c 2004-06-20 16:42:40.000000000 +0200 +++ gdc-0.8/d/dmd/constfold.c 2004-10-10 18:50:41.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #include #include #include @@ -19,6 +25,15 @@ #include "mtype.h" #include "expression.h" +#ifdef IN_GCC +#include "d-gcc-real.h" + +/* %% fix? */ +extern "C" bool real_isnan (const real_t *); + +#endif + + static real_t zero; // work around DMC bug for now @@ -112,7 +127,11 @@ } if (type->isintegral()) - return new IntegerExp(loc, e1->toInteger(), type); + { + IntegerExp * e = new IntegerExp(loc, e1->toInteger(), type); + e->toInteger(); + return e; + } if (type->isreal()) return new RealExp(loc, e1->toReal(), type); if (type->isimaginary()) @@ -273,7 +292,11 @@ if (type->isreal()) { real_t c; +#ifdef IN_GCC + c = e1->toReal() % e2->toReal(); +#else c = fmodl(e1->toReal(), e2->toReal()); +#endif e = new RealExp(loc, c, type); } else if (type->isfloating()) @@ -459,7 +482,7 @@ } #else // Don't rely on compiler, handle NAN arguments separately - if (isnan(r1) || isnan(r2)) // if unordered + if (real_isnan(&r1) || real_isnan(&r2)) // if unordered { switch (op) { @@ -585,7 +608,7 @@ #if __DMC__ cmp = (r1 == r2); #else - if (isnan(r1) || isnan(r2)) // if unordered + if (real_isnan(&r1) || real_isnan(&r2)) // if unordered { cmp = 0; } diff -uNr dmd-0.102/src/dmd/dchar.h gdc-0.8/d/dmd/dchar.h --- dmd-0.102/src/dmd/dchar.h 2003-03-04 01:44:06.000000000 +0100 +++ gdc-0.8/d/dmd/dchar.h 2004-10-02 19:19:31.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef DCHAR_H #define DCHAR_H @@ -138,7 +144,9 @@ #else #include +#ifndef GCC_SAFE_DMD #include +#endif typedef char dchar; #define TEXT(x) x @@ -156,6 +164,7 @@ static int cmp(dchar *s1, dchar *s2) { return strcmp(s1, s2); } static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); } static int isDigit(dchar c) { return '0' <= c && c <= '9'; } +#ifndef GCC_SAFE_DMD static int isAlpha(dchar c) { return isalpha(c); } static int isUpper(dchar c) { return isupper(c); } static int isLower(dchar c) { return islower(c); } @@ -165,6 +174,7 @@ static int toLower(dchar *p) { return toLower(*p); } static int toUpper(dchar c) { return islower(c) ? toupper(c) : c; } static dchar *dup(dchar *p) { return ::strdup(p); } // BUG: out of memory? +#endif static dchar *chr(dchar *p, int c) { return strchr(p, c); } static dchar *rchr(dchar *p, int c) { return strrchr(p, c); } static dchar *memchr(dchar *p, int c, int count) diff -uNr dmd-0.102/src/dmd/declaration.h gdc-0.8/d/dmd/declaration.h --- dmd-0.102/src/dmd/declaration.h 2004-09-15 01:03:26.000000000 +0200 +++ gdc-0.8/d/dmd/declaration.h 2004-10-02 19:19:31.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef DMD_DECLARATION_H #define DMD_DECLARATION_H @@ -251,6 +257,7 @@ // scopes from having the same name VarDeclaration *vthis; // 'this' parameter VarDeclaration *v_arguments; // '_arguments' parameter + VarDeclaration *v_argptr; // '_argptr' variable Array *parameters; // Array of Argument's for parameters DsymbolTable *labtab; // statement label symbol table Declaration *overnext; // next in overload list diff -uNr dmd-0.102/src/dmd/dsymbol.h gdc-0.8/d/dmd/dsymbol.h --- dmd-0.102/src/dmd/dsymbol.h 2004-08-17 00:47:36.000000000 +0200 +++ gdc-0.8/d/dmd/dsymbol.h 2004-10-02 19:19:31.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef DMD_DSYMBOL_H #define DMD_DSYMBOL_H @@ -57,7 +63,7 @@ struct ArrayScopeSymbol; struct Expression; -struct TYPE; +union tree_node; typedef union tree_node TYPE; enum PROT { diff -uNr dmd-0.102/src/dmd/enum.h gdc-0.8/d/dmd/enum.h --- dmd-0.102/src/dmd/enum.h 2004-01-19 14:38:34.000000000 +0100 +++ gdc-0.8/d/dmd/enum.h 2004-10-02 19:19:31.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef DMD_ENUM_H #define DMD_ENUM_H @@ -37,6 +43,8 @@ void toCBuffer(OutBuffer *buf); Type *getType(); char *kind(); + + void toObjFile(); }; diff -uNr dmd-0.102/src/dmd/expression.c gdc-0.8/d/dmd/expression.c --- dmd-0.102/src/dmd/expression.c 2004-09-19 12:59:50.000000000 +0200 +++ gdc-0.8/d/dmd/expression.c 2004-10-18 05:27:20.000000000 +0200 @@ -7,16 +7,29 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + +// Issues with using -include total.h (defines integer_t) and then complex.h fails... +#undef integer_t + #include #include #include #include #include +#ifdef __APPLE__ +#define integer_t dmd_integer_t +#endif + #if _WIN32 #include "..\root\mem.h" #endif -#if linux +#ifndef _WIN32 #include "../root/mem.h" #endif #include "port.h" @@ -405,7 +418,11 @@ complex_t Expression::toComplex() { error("Floating point constant expression expected instead of %s", toChars()); +#ifdef IN_GCC + return complex_t(real_t(0)); // %% nicer +#else return 0; +#endif } void Expression::toCBuffer(OutBuffer *buf) @@ -621,7 +638,7 @@ { switch (t->ty) { - case Tbit: value &= 1; break; + case Tbit: value = value != 0; break; case Tint8: value = (d_int8) value; break; case Tchar: case Tuns8: value = (d_uns8) value; break; @@ -741,14 +758,22 @@ { static char buffer[sizeof(value) * 3 + 8 + 1]; +#ifdef IN_GCC + value.format(buffer, sizeof(buffer)); +#else sprintf(buffer, "%Lg", value); +#endif assert(strlen(buffer) < sizeof(buffer)); return buffer; } integer_t RealExp::toInteger() { +#ifdef IN_GCC + return value.toInt(); +#else return (integer_t) value; +#endif } real_t RealExp::toReal() @@ -763,7 +788,7 @@ complex_t RealExp::toComplex() { - return value; + return complex_t(value); } Expression *RealExp::semantic(Scope *sc) @@ -777,13 +802,23 @@ int RealExp::isBool(int result) { +#ifdef IN_GCC + return result ? (! value.isZero()) : (value.isZero()); +#else return result ? (value != 0) : (value == 0); +#endif } void RealExp::toCBuffer(OutBuffer *buf) { +#ifdef IN_GCC + char buffer[3 + 3 * sizeof(value) + 1]; + value.format(buffer, sizeof(buffer)); + buf->writestring(buffer); +#else buf->printf("%Lg", value); +#endif } @@ -800,7 +835,12 @@ { static char buffer[sizeof(value) * 3 + 8 + 1]; +#ifdef IN_GCC + value.format(buffer, sizeof(buffer)); + strcat(buffer, "i"); +#else sprintf(buffer, "%Lgi", value); +#endif assert(strlen(buffer) < sizeof(buffer)); return buffer; } @@ -822,7 +862,7 @@ complex_t ImaginaryExp::toComplex() { - return value; + return complex_t(0, value); } Expression *ImaginaryExp::semantic(Scope *sc) @@ -836,13 +876,24 @@ int ImaginaryExp::isBool(int result) { +#ifdef IN_GCC + return result ? (! value.isZero()) : (value.isZero()); +#else return result ? (value != 0) : (value == 0); +#endif } void ImaginaryExp::toCBuffer(OutBuffer *buf) { - buf->printf("%Lgi", value); +#ifdef IN_GCC + char buffer[3 + 3 * sizeof(value) + 1]; + value.format(buffer, sizeof(buffer)); + strcat(buffer, "i"); // %% buffer + buf->writestring(buffer); +#else + buf->printf("%Lg", value); +#endif } @@ -859,8 +910,16 @@ { static char buffer[sizeof(value) * 3 + 8 + 1]; +#ifdef IN_GCC + char buf1[sizeof(value) * 3 + 8 + 1]; + char buf2[sizeof(value) * 3 + 8 + 1]; + creall(value).format(buf1, sizeof(buf1)); + cimagl(value).format(buf2, sizeof(buf2)); + sprintf(buffer, "(%s+%si)", buf1, buf2); +#else sprintf(buffer, "(%Lg+%Lgi)", creall(value), cimagl(value)); assert(strlen(buffer) < sizeof(buffer)); +#endif return buffer; } @@ -901,7 +960,15 @@ void ComplexExp::toCBuffer(OutBuffer *buf) { +#ifdef IN_GCC + char buf1[sizeof(value) * 3 + 8 + 1]; + char buf2[sizeof(value) * 3 + 8 + 1]; + creall(value).format(buf1, sizeof(buf1)); + cimagl(value).format(buf2, sizeof(buf2)); + buf->printf("(%s+%si)", buf1, buf2); +#else buf->printf("(%Lg+%Lgi)", creall(value), cimagl(value)); +#endif } @@ -4518,7 +4585,7 @@ #endif if (e1->op == TOKstring && e2->op == TOKstring) e = optimize(WANTvalue); - else if (e1->type-equals(e2->type) && + else if (e1->type->equals(e2->type) && (e1->type->toBasetype()->ty == Tarray || e1->type->toBasetype()->ty == Tsarray)) { diff -uNr dmd-0.102/src/dmd/expression.h gdc-0.8/d/dmd/expression.h --- dmd-0.102/src/dmd/expression.h 2004-09-15 01:23:00.000000000 +0200 +++ gdc-0.8/d/dmd/expression.h 2004-10-02 19:19:31.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef DMD_EXPRESSION_H #define DMD_EXPRESSION_H @@ -36,7 +42,7 @@ // Back end struct IRState; -struct elem; +union tree_node; typedef union tree_node elem; struct dt_t; Expression *resolveProperties(Scope *sc, Expression *e); diff -uNr dmd-0.102/src/dmd/func.c gdc-0.8/d/dmd/func.c --- dmd-0.102/src/dmd/func.c 2004-08-26 00:55:50.000000000 +0200 +++ gdc-0.8/d/dmd/func.c 2004-10-15 01:21:22.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #include #include @@ -44,6 +50,7 @@ localsymtab = NULL; vthis = NULL; v_arguments = NULL; + v_argptr = NULL; parameters = NULL; labtab = NULL; overnext = NULL; @@ -123,6 +130,13 @@ } #endif +#ifdef IN_GCC + AggregateDeclaration *ad; + + ad = parent->isAggregateDeclaration(); + if (ad) + ad->methods.push(this); +#endif sd = parent->isStructDeclaration(); if (sd) { @@ -431,7 +445,12 @@ } if (f->linkage == LINKd || (parameters && parameters->dim)) { // Declare _argptr +#ifndef IN_GCC t = Type::tvoid->pointerTo(); +#else + extern Type * d_gcc_builtin_va_list_d_type; + t = d_gcc_builtin_va_list_d_type; +#endif argptr = new VarDeclaration(0, t, Id::_argptr, NULL); argptr->semantic(sc2); sc2->insert(argptr); @@ -628,6 +647,7 @@ { // Initialize _argptr to point past non-variadic arg Expression *e1; Expression *e; +#ifndef IN_GCC Type *t = argptr->type; VarDeclaration *p; unsigned offset; @@ -642,6 +662,11 @@ e = new SymOffExp(0, p, offset); e = new AssignExp(0, e1, e); e->type = t; +#else + v_argptr = argptr; + e = new DeclarationExp(0, argptr); + e->type = Type::tvoid; +#endif a->push(new ExpStatement(0, e)); } diff -uNr dmd-0.102/src/dmd/html.c gdc-0.8/d/dmd/html.c --- dmd-0.102/src/dmd/html.c 2004-02-21 12:30:44.000000000 +0100 +++ gdc-0.8/d/dmd/html.c 2004-10-23 22:44:51.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + /* HTML parser */ @@ -27,7 +33,7 @@ inline int istagstart(int c) { - return (isalpha(c) || c == '_'); + return (isalpha(c) || c == '_' || c == '!'); } inline int istag(int c) @@ -55,7 +61,7 @@ void Html::error(const char *format, ...) { - printf("%s(%d) : HTML Error: ", sourcename, linnum); + printf("%s:%d: HTML Error: ", sourcename, linnum); va_list ap; va_start(ap, format); @@ -240,7 +246,7 @@ } // See if we parsed a or tag - if (taglen && memicmp((char *)tagstart, "CODE", taglen) == 0) + if (taglen && memicmp((const char *)tagstart, "CODE", taglen) == 0) { if (nottag) { inCode--; @@ -519,6 +525,7 @@ "not", 172, "shy", 173, "reg", 174, + NULL, 0 // BUG: This is only a partial list. // For the rest, consult: @@ -530,7 +537,7 @@ int i; // BUG: this is a dumb, slow linear search - for (i = 0; i < sizeof(names) / sizeof(names[0]); i++) + for (i = 0; names[i].name; i++) { // Do case insensitive compare if (memicmp(names[i].name, (char *)p, length) == 0) diff -uNr dmd-0.102/src/dmd/init.h gdc-0.8/d/dmd/init.h --- dmd-0.102/src/dmd/init.h 2004-09-15 01:04:32.000000000 +0200 +++ gdc-0.8/d/dmd/init.h 2004-10-02 19:19:31.000000000 +0200 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2004 by Digital Mars +// Copyright (c) 1999-2002 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com diff -uNr dmd-0.102/src/dmd/lexer.c gdc-0.8/d/dmd/lexer.c --- dmd-0.102/src/dmd/lexer.c 2004-08-30 02:08:24.000000000 +0200 +++ gdc-0.8/d/dmd/lexer.c 2004-10-02 19:19:31.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + /* Lexical Analyzer */ #include @@ -18,13 +24,13 @@ #include #include -#if __GNUC__ +#if ! HAVE_DECL_STRTOLD extern "C" long double strtold(const char *p,char **endp); #endif #if _WIN32 #include "..\root\mem.h" -#elif linux +#elif ! defined(_WIN32) #include "../root/mem.h" #else #error "fix this" @@ -102,14 +108,14 @@ switch (value) { case TOKint32v: - sprintf(buffer,"%ld",int32value); + sprintf(buffer,"%ld",(d_int32)int64value); break; case TOKuns32v: case TOKcharv: case TOKwcharv: case TOKdcharv: - sprintf(buffer,"%luU",uns32value); + sprintf(buffer,"%luU",(d_uns32)uns64value); break; case TOKint64v: @@ -120,6 +126,20 @@ sprintf(buffer,"%lluUL",uns64value); break; +#if IN_GCC + case TOKfloat32v: + case TOKfloat64v: + case TOKfloat80v: + float80value.format(buffer, sizeof(buffer)); + break; + case TOKimaginary32v: + case TOKimaginary64v: + case TOKimaginary80v: + float80value.format(buffer, sizeof(buffer)); + // %% buffer + strcat(buffer, "i"); + break; +#else case TOKfloat32v: sprintf(buffer,"%Lgf", float80value); break; @@ -143,6 +163,7 @@ case TOKimaginary80v: sprintf(buffer,"%gLi", float80value); break; +#endif case TOKstring: @@ -1684,7 +1705,9 @@ { case 'F': case 'f': -#if __GNUC__ +#ifdef IN_GCC + t->float80value = real_t::parse((char *)stringbuffer.data, real_t::Float); +#elif __GNUC__ t->float80value = strtod((char *)stringbuffer.data, NULL); #else t->float80value = strtof((char *)stringbuffer.data, NULL); @@ -1694,13 +1717,19 @@ break; default: +#ifdef IN_GCC + t->float80value = real_t::parse((char *)stringbuffer.data, real_t::Double); +#else t->float80value = strtod((char *)stringbuffer.data, NULL); +#endif result = TOKfloat64v; break; case 'L': case 'l': -#if 0 +#ifdef IN_GCC + t->float80value = real_t::parse((char *)stringbuffer.data, real_t::LongDouble); +#elif 0 t->float80value = strtod((char *)stringbuffer.data, NULL); #else t->float80value = strtold((char *)stringbuffer.data, NULL); diff -uNr dmd-0.102/src/dmd/lexer.h gdc-0.8/d/dmd/lexer.h --- dmd-0.102/src/dmd/lexer.h 2004-08-30 02:08:24.000000000 +0200 +++ gdc-0.8/d/dmd/lexer.h 2004-10-02 19:19:31.000000000 +0200 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef DMD_LEXER_H #define DMD_LEXER_H @@ -190,7 +196,11 @@ d_uns64 uns64value; // Floats +#ifdef IN_GCC + //real_t float80value; // can't use this in a union! +#else d_float80 float80value; +#endif struct { unsigned char *ustring; // UTF8 string @@ -198,6 +208,9 @@ }; Identifier *ident; }; +#ifdef IN_GCC + real_t float80value; // can't use this in a union! +#endif static char *tochars[TOKMAX]; static void *operator new(size_t sz); diff -uNr dmd-0.102/src/dmd/mars.h gdc-0.8/d/dmd/mars.h --- dmd-0.102/src/dmd/mars.h 2004-03-11 21:06:28.000000000 +0100 +++ gdc-0.8/d/dmd/mars.h 2004-10-02 19:19:31.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef DMD_MARS_H #define DMD_MARS_H @@ -97,15 +103,16 @@ #ifdef __DMC__ typedef _Complex long double complex_t; #else +#ifndef IN_GCC #include "complex_t.h" +#endif #ifdef __APPLE__ -#include "complex.h" +//#include "complex.h"//This causes problems with include the c++ and not the C "complex.h" #define integer_t dmd_integer_t #endif #endif typedef unsigned long long integer_t; -typedef long double real_t; typedef signed char d_int8; typedef unsigned char d_uns8; @@ -123,15 +130,24 @@ // Note: this will be 2 bytes on Win32 systems, and 4 bytes under linux. typedef wchar_t d_wchar; +#ifdef IN_GCC +#include "d-gcc-real.h" +#else +typedef long double real_t; +#endif // Modify OutBuffer::writewchar to write the correct size of wchar #if _WIN32 #define writewchar writeword #endif -#if linux +// This needs a configuration test... +#ifndef _WIN32 #define writewchar write4 #endif +#ifdef IN_GCC +#include "d-gcc-complex_t.h" +#endif struct Module; @@ -158,8 +174,10 @@ char *toChars(); }; +#ifndef GCC_SAFE_DMD #define TRUE 1 #define FALSE 0 +#endif #define INTERFACE_OFFSET 0 // if 1, put classinfo as first entry // in interface vtbl[]'s diff -uNr dmd-0.102/src/dmd/mem.h gdc-0.8/d/dmd/mem.h --- dmd-0.102/src/dmd/mem.h 2004-01-02 02:47:06.000000000 +0100 +++ gdc-0.8/d/dmd/mem.h 2004-10-02 19:19:31.000000000 +0200 @@ -1,10 +1,16 @@ // Copyright (C) 2000-2001 by Chromium Communications // All Rights Reserved +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef ROOT_MEM_H #define ROOT_MEM_H -typedef unsigned size_t; +#include // for size_t typedef void (*FINALIZERPROC)(void* pObj, void* pClientData); diff -uNr dmd-0.102/src/dmd/module.c gdc-0.8/d/dmd/module.c --- dmd-0.102/src/dmd/module.c 2004-08-30 01:22:16.000000000 +0200 +++ gdc-0.8/d/dmd/module.c 2004-10-02 19:19:31.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #include #include #include @@ -113,6 +119,10 @@ return "module"; } +#ifdef IN_GCC +extern void d_gcc_magic_module(Module *m); +#endif + Module *Module::load(Loc loc, Array *packages, Identifier *ident) { Module *m; char *filename; @@ -159,6 +169,10 @@ m->read(); m->parse(); +#ifdef IN_GCC + d_gcc_magic_module(m); +#endif + return m; } diff -uNr dmd-0.102/src/dmd/module.h gdc-0.8/d/dmd/module.h --- dmd-0.102/src/dmd/module.h 2004-09-06 23:39:32.000000000 +0200 +++ gdc-0.8/d/dmd/module.h 2004-10-02 19:19:31.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef DMD_MODULE_H #define DMD_MODULE_H @@ -22,7 +28,7 @@ struct ModuleDeclaration; // Back end -struct elem; +union tree_node; typedef union tree_node elem; struct Package : ScopeDsymbol { diff -uNr dmd-0.102/src/dmd/mtype.c gdc-0.8/d/dmd/mtype.c --- dmd-0.102/src/dmd/mtype.c 2004-09-20 00:42:24.000000000 +0200 +++ gdc-0.8/d/dmd/mtype.c 2004-10-02 19:19:31.000000000 +0200 @@ -7,6 +7,15 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + +// Issues with using -include total.h (defines integer_t) and then complex.h fails... +#undef integer_t + #include #include @@ -15,18 +24,39 @@ #endif #include +// TODO%% this undefines signbit and includes is the wrong complex.h anyway +// -- not sure why this is needed, anyway +// don't need to worry about all this if the 'nan negative by default' issue is resolved +#ifndef __GNUC__ +// includes the wrong complex.h in C++ #include +#endif #ifdef __APPLE__ #include static double zero = 0; #elif __GNUC__ #include -#include -#include +// %% shouldn't be necessary +//#include +//#include static double zero = 0; #endif +#ifndef NAN +#define NAN (nan("0")) +#endif +#ifndef INFINITY +#define INFINITY (infinity()) +#endif + + + +#ifdef __APPLE__ +#define integer_t dmd_integer_t +#endif + + #include "mem.h" #include "mtype.h" @@ -806,7 +836,11 @@ { Expression *e; d_int64 ivalue; +#ifdef IN_GCC + real_t fvalue; +#else d_float80 fvalue; +#endif //printf("TypeBasic::getProperty('%s')\n", ident->toChars()); if (ident == Id::max) @@ -828,6 +862,38 @@ case Tcomplex32: case Timaginary32: +#ifdef IN_GCC + // %% lazy, fix +#define FLT_MAX real_t_properties[real_t::Float].maxval; +#define DBL_MAX real_t_properties[real_t::Double].maxval; +#define LDBL_MAX real_t_properties[real_t::LongDouble].maxval; +#define FLT_MIN real_t_properties[real_t::Float].minval; +#define DBL_MIN real_t_properties[real_t::Double].minval; +#define LDBL_MIN real_t_properties[real_t::LongDouble].minval; +#define FLT_DIG real_t_properties[real_t::Float].dig; +#define DBL_DIG real_t_properties[real_t::Double].dig; +#define LDBL_DIG real_t_properties[real_t::LongDouble].dig; +#define FLT_MANT_DIG real_t_properties[real_t::Float].mant_dig; +#define DBL_MANT_DIG real_t_properties[real_t::Double].mant_dig; +#define LDBL_MANT_DIG real_t_properties[real_t::LongDouble].mant_dig; +#define FLT_MAX_10_EXP real_t_properties[real_t::Float].max_10_exp; +#define DBL_MAX_10_EXP real_t_properties[real_t::Double].max_10_exp; +#define LDBL_MAX_10_EXP real_t_properties[real_t::LongDouble].max_10_exp; +#define FLT_MIN_10_EXP real_t_properties[real_t::Float].min_10_exp; +#define DBL_MIN_10_EXP real_t_properties[real_t::Double].min_10_exp; +#define LDBL_MIN_10_EXP real_t_properties[real_t::LongDouble].min_10_exp; +#define FLT_MAX_EXP real_t_properties[real_t::Float].max_exp; +#define DBL_MAX_EXP real_t_properties[real_t::Double].max_exp; +#define LDBL_MAX_EXP real_t_properties[real_t::LongDouble].max_exp; +#define FLT_MIN_EXP real_t_properties[real_t::Float].min_exp; +#define DBL_MIN_EXP real_t_properties[real_t::Double].min_exp; +#define LDBL_MIN_EXP real_t_properties[real_t::LongDouble].min_exp; +#define FLT_EPSILON real_t_properties[real_t::Float].epsilonval; +#define DBL_EPSILON real_t_properties[real_t::Double].epsilonval; +#define LDBL_EPSILON real_t_properties[real_t::LongDouble].epsilonval; + + +#endif case Tfloat32: fvalue = FLT_MAX; goto Lfvalue; case Tcomplex64: case Timaginary64: @@ -878,13 +944,18 @@ case Tfloat32: case Tfloat64: case Tfloat80: -#if __GNUC__ +#ifdef IN_GCC + // mode doesn't matter, will be converted in RealExp anyway + fvalue = real_t::getnan(real_t::LongDouble); +#elif __GNUC__ { // gcc nan's have the sign bit set by default, so turn it off // Need the volatile to prevent gcc from doing incorrect // constant folding. volatile d_float80 foo; foo = NAN; - foo = -foo; + // This doesn't seem to be the case on the systems I'm using %% + if ( signbit(foo) ) + foo = -foo; fvalue = foo; } #else @@ -906,7 +977,9 @@ case Tfloat32: case Tfloat64: case Tfloat80: -#if __GNUC__ +#ifdef IN_GCC + fvalue = real_t::getinfinity(); +#elif __GNUC__ fvalue = 1 / zero; #else fvalue = INFINITY; @@ -1078,7 +1151,7 @@ case Timaginary64: t = tfloat64; goto L2; case Timaginary80: t = tfloat80; goto L2; L2: - e = new RealExp(0, 0.0, t); + e = new RealExp(0, 0, t); break; default: @@ -1108,7 +1181,7 @@ case Tfloat32: case Tfloat64: case Tfloat80: - e = new RealExp(0, 0.0, this); + e = new RealExp(0, 0, this); break; default: @@ -1265,7 +1338,7 @@ assert(size); nm = name[n->ty == Tbit][ident == Id::dup]; - fd = FuncDeclaration::genCfunc(Type::tindex, nm); + fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), nm); ec = new VarExp(0, fd); e = e->castTo(n->arrayOf()); // convert to dynamic array arguments = new Array(); @@ -1340,7 +1413,7 @@ buf->writeByte('['); dim = ((TypeSArray *)t)->dim; if (dim) - buf->printf("%d", dim->toInteger()); + buf->printf("%lld", dim->toInteger()); buf->writeByte(']'); t = t->next; } while (t->ty == Tsarray); @@ -1790,7 +1863,7 @@ else #endif strcpy(aakeys, "_aaKeys"); - fd = FuncDeclaration::genCfunc(Type::tindex, aakeys); + fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), aakeys); ec = new VarExp(0, fd); arguments = new Array(); arguments->push(e); @@ -1805,7 +1878,7 @@ FuncDeclaration *fd; Array *arguments; - fd = FuncDeclaration::genCfunc(Type::tindex, "_aaValues"); + fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), "_aaValues"); ec = new VarExp(0, fd); arguments = new Array(); arguments->push(e); @@ -1820,7 +1893,7 @@ FuncDeclaration *fd; Array *arguments; - fd = FuncDeclaration::genCfunc(Type::tint64, "_aaRehash"); + fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), "_aaRehash"); ec = new VarExp(0, fd); arguments = new Array(); arguments->push(e->addressOf()); diff -uNr dmd-0.102/src/dmd/mtype.h gdc-0.8/d/dmd/mtype.h --- dmd-0.102/src/dmd/mtype.h 2004-09-20 00:42:14.000000000 +0200 +++ gdc-0.8/d/dmd/mtype.h 2004-10-02 19:19:31.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef DMD_MTYPE_H #define DMD_MTYPE_H @@ -35,7 +41,8 @@ struct TypeBasic; // Back end -typedef struct TYPE type; +union tree_node; typedef union tree_node TYPE; +typedef TYPE type; struct Symbol; enum TY diff -uNr dmd-0.102/src/dmd/opover.c gdc-0.8/d/dmd/opover.c --- dmd-0.102/src/dmd/opover.c 2004-07-26 23:08:46.000000000 +0200 +++ gdc-0.8/d/dmd/opover.c 2004-10-02 19:19:31.000000000 +0200 @@ -6,13 +6,27 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + + +// Issues with using -include total.h (defines integer_t) and then complex.h fails... +#undef integer_t + #include #include #include #include #include -#if linux +#ifdef __APPLE__ +#define integer_t dmd_integer_t +#endif + +#ifndef _WIN32 #include "../root/mem.h" #endif #if _WIN32 diff -uNr dmd-0.102/src/dmd/parse.c gdc-0.8/d/dmd/parse.c --- dmd-0.102/src/dmd/parse.c 2004-08-30 02:11:28.000000000 +0200 +++ gdc-0.8/d/dmd/parse.c 2004-10-02 19:19:31.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #include #include @@ -3416,12 +3422,12 @@ break; case TOKint32v: - e = new IntegerExp(loc, token.int32value, Type::tint32); + e = new IntegerExp(loc, (d_int32)token.int64value, Type::tint32); nextToken(); break; case TOKuns32v: - e = new IntegerExp(loc, token.uns32value, Type::tuns32); + e = new IntegerExp(loc, (d_uns32)token.uns64value, Type::tuns32); nextToken(); break; @@ -3481,17 +3487,17 @@ break; case TOKcharv: - e = new IntegerExp(loc, token.uns32value, Type::tchar); + e = new IntegerExp(loc, (d_uns32)token.uns64value, Type::tchar); nextToken(); break; case TOKwcharv: - e = new IntegerExp(loc, token.uns32value, Type::twchar); + e = new IntegerExp(loc, (d_uns32)token.uns64value, Type::twchar); nextToken(); break; case TOKdcharv: - e = new IntegerExp(loc, token.uns32value, Type::tdchar); + e = new IntegerExp(loc, (d_uns32)token.uns64value, Type::tdchar); nextToken(); break; diff -uNr dmd-0.102/src/dmd/root.c gdc-0.8/d/dmd/root.c --- dmd-0.102/src/dmd/root.c 2003-12-24 02:48:34.000000000 +0100 +++ gdc-0.8/d/dmd/root.c 2004-10-08 03:26:57.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #include #include #include @@ -21,7 +27,7 @@ #include #endif -#if linux +#ifndef _WIN32 #include #include #include @@ -320,7 +326,7 @@ namelen = strlen(name); f = (char *)mem.malloc(pathlen + 1 + namelen + 1); memcpy(f, path, pathlen); -#if linux +#ifndef _WIN32 if (path[pathlen - 1] != '/') { f[pathlen] = '/'; pathlen++; @@ -374,7 +380,7 @@ #if _WIN32 case ';': #endif -#if linux +#ifndef _WIN32 case ':': #endif p++; @@ -388,7 +394,7 @@ case '\r': continue; // ignore carriage returns -#if linux +#ifndef _WIN32 case '~': buf.writestring(getenv("HOME")); continue; @@ -416,7 +422,8 @@ unsigned FileName::hashCode() { -#if linux +#ifndef _WIN32 + // darwin HFS is case insensitive, though... return String::hashCode(); #endif #if _WIN32 @@ -461,7 +468,7 @@ int FileName::compare(Object *obj) { -#if linux +#ifndef _WIN32 return String::compare(obj); #endif #if _WIN32 @@ -471,7 +478,7 @@ int FileName::equals(Object *obj) { -#if linux +#ifndef _WIN32 return String::equals(obj); #endif #if _WIN32 @@ -490,7 +497,7 @@ (*name == '/') || (*name && name[1] == ':'); #endif -#if linux +#ifndef _WIN32 return (*name == '/'); #endif } @@ -511,7 +518,7 @@ switch (*e) { case '.': return e + 1; -#if linux +#ifndef _WIN32 case '/': break; #endif @@ -549,7 +556,7 @@ { switch (*e) { -#if linux +#ifndef _WIN32 case '/': return e + 1; #endif @@ -586,7 +593,7 @@ if (n > str) { -#if linux +#ifndef _WIN32 if (n[-1] == '/') n--; #endif @@ -622,7 +629,7 @@ namelen = strlen(name); f = (char *)mem.malloc(pathlen + 1 + namelen + 1); memcpy(f, path, pathlen); -#if linux +#ifndef _WIN32 if (path[pathlen - 1] != '/') { f[pathlen] = '/'; pathlen++; @@ -698,7 +705,7 @@ return 1; if (!e || !ext) return 0; -#if linux +#ifndef _WIN32 return strcmp(e,ext) == 0; #endif #if _WIN32 @@ -717,7 +724,7 @@ #if _WIN32 file.touchtime = mem.malloc(sizeof(WIN32_FIND_DATAA)); // keep same file time #endif -#if linux +#ifndef _WIN32 file.touchtime = mem.malloc(sizeof(struct stat)); // keep same file time #endif file.readv(); @@ -759,7 +766,7 @@ int FileName::exists(const char *name) { -#if linux +#ifndef _WIN32 struct stat st; if (stat(name, &st) < 0) @@ -830,7 +837,7 @@ int File::read() { -#if linux +#ifndef _WIN32 off_t size; ssize_t numread; int fd; @@ -962,7 +969,7 @@ int File::mmread() { -#if linux +#ifndef _WIN32 return read(); #endif #if _WIN32 @@ -1016,7 +1023,7 @@ int File::write() { -#if linux +#ifndef _WIN32 int fd; ssize_t numwritten; char *name; @@ -1087,7 +1094,7 @@ int File::append() { -#if linux +#ifndef _WIN32 return 1; #endif #if _WIN32 @@ -1167,7 +1174,7 @@ int File::exists() { -#if linux +#ifndef _WIN32 return 0; #endif #if _WIN32 @@ -1192,7 +1199,7 @@ void File::remove() { -#if linux +#ifndef _WIN32 ::remove(this->name->toChars()); #endif #if _WIN32 @@ -1207,7 +1214,7 @@ Array *File::match(FileName *n) { -#if linux +#ifndef _WIN32 return NULL; #endif #if _WIN32 @@ -1245,7 +1252,7 @@ int File::compareTime(File *f) { -#if linux +#ifndef _WIN32 return 0; #endif #if _WIN32 @@ -1259,7 +1266,7 @@ void File::stat() { -#if linux +#ifndef _WIN32 if (!touchtime) { touchtime = mem.calloc(1, sizeof(struct stat)); @@ -1564,7 +1571,7 @@ break; psize *= 2; #endif -#if linux +#ifndef _WIN32 count = vsnprintf(p,psize,format,args); if (count == -1) psize *= 2; @@ -1596,7 +1603,7 @@ break; psize *= 2; #endif -#if linux +#ifndef _WIN32 count = vsnwprintf(p,psize,format,args); if (count == -1) psize *= 2; @@ -1713,7 +1720,7 @@ // Clear other bits in last word mask = (1 << (bitdim & 31)) - 1; if (mask) - data[allocdim - 1] &= ~mask; + data[allocdim - 1] &= mask; } void Bits::clear() diff -uNr dmd-0.102/src/dmd/root.h gdc-0.8/d/dmd/root.h --- dmd-0.102/src/dmd/root.h 2004-01-02 02:47:10.000000000 +0100 +++ gdc-0.8/d/dmd/root.h 2004-10-02 19:19:31.000000000 +0200 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef ROOT_H #define ROOT_H @@ -27,9 +33,11 @@ int bstrcmp(unsigned char *s1, unsigned char *s2); char *bstr2str(unsigned char *b); +#ifndef GCC_SAFE_DMD void error(const char *format, ...); void error(const wchar_t *format, ...); void warning(const char *format, ...); +#endif #ifndef TYPEDEFS #define TYPEDEFS diff -uNr dmd-0.102/src/dmd/statement.c gdc-0.8/d/dmd/statement.c --- dmd-0.102/src/dmd/statement.c 2004-09-16 03:02:46.000000000 +0200 +++ gdc-0.8/d/dmd/statement.c 2004-10-02 19:19:31.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #include #include #include @@ -1294,6 +1300,7 @@ : Statement(loc) { this->statement = s; + cblock = NULL; } Statement *DefaultStatement::syntaxCopy() diff -uNr dmd-0.102/src/dmd/statement.h gdc-0.8/d/dmd/statement.h --- dmd-0.102/src/dmd/statement.h 2003-12-17 22:46:00.000000000 +0100 +++ gdc-0.8/d/dmd/statement.h 2004-10-02 19:19:31.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef DMD_STATEMENT_H #define DMD_STATEMENT_H @@ -40,8 +46,8 @@ // Back end struct IRState; struct Blockx; -struct block; -struct elem; +union tree_node; typedef union tree_node block; +union tree_node; typedef union tree_node elem; struct code; struct Statement : Object @@ -331,6 +337,7 @@ struct DefaultStatement : Statement { Statement *statement; + block *cblock; // back end: label for the block DefaultStatement(Loc loc, Statement *s); Statement *syntaxCopy(); diff -uNr dmd-0.102/src/dmd/template.c gdc-0.8/d/dmd/template.c --- dmd-0.102/src/dmd/template.c 2004-09-19 02:17:58.000000000 +0200 +++ gdc-0.8/d/dmd/template.c 2004-09-29 04:25:49.000000000 +0200 @@ -1179,6 +1179,14 @@ idents.push(ident); } +#ifdef IN_GCC +// This is needed for -femit-templates=private work-around. We +// must ensure the TemplateInstance ends up as a member of the +// module that is being compiled so that the template instance's +// toObjfile is called. +extern Module * getCurrentModule(); +#endif + void TemplateInstance::semantic(Scope *sc) { #if LOG @@ -1305,6 +1313,10 @@ #if 1 { Array *a; int i; +#ifdef IN_GCC + // For gcc, always add it the module that is being compiled + a = getCurrentModule()->members; +#else if (sc->scopesym && sc->scopesym->members) { @@ -1316,6 +1328,7 @@ //printf("\t2: adding to module %s\n", sc->module->importedFrom->toChars()); a = sc->module->importedFrom->members; } +#endif for (i = 0; 1; i++) { if (i == a->dim) @@ -1643,7 +1656,7 @@ goto Lsa; } buf.writeByte('_'); - buf.printf("%u", ea->toInteger()); + buf.printf("%llu", ea->toInteger()); } else if (sa) { diff -uNr dmd-0.102/src/dmd/todt.c gdc-0.8/d/dmd/todt.c --- dmd-0.102/src/dmd/todt.c 2004-08-09 17:49:20.000000000 +0200 +++ gdc-0.8/d/dmd/todt.c 2004-10-25 00:28:38.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + /* A dt_t is a simple structure representing data to be added * to the data segment of the output object file. As such, * it is a list of initialized bytes, 0 data, and offsets from @@ -15,12 +21,17 @@ * be written to the data segment. */ +#undef integer_t #include #include #include #include #include +#ifdef __APPLE__ +#define integer_t dmd_integer_t +#endif + #include "lexer.h" #include "mtype.h" #include "expression.h" @@ -31,12 +42,14 @@ // Back end +#ifndef IN_GCC #include "cc.h" #include "el.h" #include "oper.h" #include "global.h" #include "code.h" #include "type.h" +#endif #include "dt.h" extern Symbol *static_sym(); @@ -102,6 +115,23 @@ { d = v->init->toDt(); } + else if (v->offset >= offset) + { + unsigned k; + unsigned offset2 = v->offset + v->type->size(); + // Make sure this field does not overlap any explicitly + // initialized field. + for (k = j + 1; k < dts.dim; k++) + { + VarDeclaration *v2 = (VarDeclaration *)ad->fields.data[k]; + + if (v2->offset < offset2 && dts.data[k]) { + break; + } + } + if (k == dts.dim) + v->type->toDt(& d); + } } if (d) { @@ -170,7 +200,7 @@ if (dt) pdtend = dtcat(pdtend, dt); else - pdtend = dtnzeros(pdtend, size); + pdtend = tn->toDt(pdtend); } switch (tb->ty) { @@ -219,8 +249,22 @@ Bits databits; Bits initbits; - databits.resize(dim); - initbits.resize(dim); + if (tb->ty == Tsarray) + { + /* Need to resize to the size of the static array, otherwise set() will + affect bits beyond the last specified element. */ + unsigned sdim = ((TypeSArray*)tb)->dim->toInteger(); // missing overflow check + databits.resize(sdim); + initbits.resize(sdim); + } + else + { + databits.resize(dim); + initbits.resize(dim); + } + + if (tb->next->defaultInit()->toInteger()) + databits.set(); size = sizeof(databits.data[0]); @@ -242,7 +286,7 @@ if (initbits.test(length)) error("duplicate initializations for index %d", length); initbits.set(length); - if (bitval & 1) + if (bitval != 0) databits.set(length); else databits.clear(length); @@ -250,7 +294,11 @@ } d = NULL; +#ifdef IN_GCC + pdtend = dtnbits(&d, databits.allocdim * size, (char *)databits.data, sizeof(databits.data[0])); +#else pdtend = dtnbytes(&d, databits.allocdim * size, (char *)databits.data); +#endif switch (tb->ty) { case Tsarray: @@ -309,6 +357,8 @@ return pdt; } +#ifndef IN_GCC + dt_t **IntegerExp::toDt(dt_t **pdt) { unsigned sz; @@ -419,6 +469,9 @@ return pdt; } + +#endif + dt_t **NullExp::toDt(dt_t **pdt) { assert(type); @@ -434,14 +487,22 @@ { case Tarray: dtdword(pdt, len); +#ifndef IN_GCC pdt = dtabytes(pdt, TYnptr, 0, (len + 1) * sz, (char *)string); +#else + pdt = dtawords(pdt, len + 1, string, sz); +#endif break; case Tsarray: { TypeSArray *tsa = (TypeSArray *)type; integer_t dim; +#ifndef IN_GCC pdt = dtnbytes(pdt, len * sz, (char *)string); +#else + pdt = dtnwords(pdt, len, string, sz); +#endif if (tsa->dim) { dim = tsa->dim->toInteger(); @@ -454,7 +515,11 @@ break; } case Tpointer: +#ifndef IN_GCC pdt = dtabytes(pdt, TYnptr, 0, (len + 1) * sz, (char *)string); +#else + pdt = dtawords(pdt, len + 1, string, sz); +#endif break; default: @@ -641,17 +706,33 @@ { while (*pdt) pdt = &((*pdt)->DTnext); - next->toDt(pdt); - if ((*pdt)->dt == DT_azeros && !(*pdt)->DTnext) + if (next->toBasetype()->ty != Tbit) { - (*pdt)->DTazeros *= len; + next->toDt(pdt); + if ((*pdt)->dt == DT_azeros && !(*pdt)->DTnext) + { + (*pdt)->DTazeros *= len; + } + else + { + for (i = 1; i < len; i++) + { + pdt = next->toDt(pdt); + } + } } else { - for (i = 1; i < len; i++) - { - pdt = next->toDt(pdt); - } + Bits databits; + + databits.resize(len); + if (next->defaultInit()->toInteger()) + databits.set(); +#ifdef IN_GCC + pdt = dtnbits(pdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data, sizeof(databits.data[0])); +#else + pdt = dtnbytes(pdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data); +#endif } } return pdt; diff -uNr dmd-0.102/src/dmd/toobj.c gdc-0.8/d/dmd/toobj.c --- dmd-0.102/src/dmd/toobj.c 2004-09-19 02:18:12.000000000 +0200 +++ gdc-0.8/d/dmd/toobj.c 2004-10-08 03:26:57.000000000 +0200 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #include #include #include @@ -26,6 +32,7 @@ #include "template.h" #include +#ifndef IN_GCC #include "cc.h" #include "global.h" #include "oper.h" @@ -35,6 +42,9 @@ #include "cgcv.h" #include "outbuf.h" #include "irstate.h" +#else +#include "dt.h" +#endif /* ================================================================== */ @@ -164,13 +174,11 @@ } /* ================================================================== */ - void Dsymbol::toObjFile() { //printf("Dsymbol::toObjFile('%s')\n", toChars()); // ignore } - /* ================================================================== */ void ClassDeclaration::toObjFile() @@ -808,10 +816,27 @@ dim = ((TypeSArray *)tb)->dim->toInteger(); - // Duplicate Sdt 'dim-1' times, as we already have the first one - while (--dim > 0) + if (tb->next->toBasetype()->ty != Tbit) { - ie->exp->toDt(&s->Sdt); + // Duplicate Sdt 'dim-1' times, as we already have the first one + while (--dim > 0) + { + ie->exp->toDt(&s->Sdt); + } + } + else + { + Bits databits; + + databits.resize(dim); + if (ie->exp->toInteger()) + databits.set(); + s->Sdt = NULL; +#ifdef IN_GCC + dtnbits(& s->Sdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data, sizeof(databits.data[0])); +#else + dtnbytes(& s->Sdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data); +#endif } } } diff -uNr dmd-0.102/src/dmd/typinf.c gdc-0.8/d/dmd/typinf.c --- dmd-0.102/src/dmd/typinf.c 2004-08-17 14:39:56.000000000 +0200 +++ gdc-0.8/d/dmd/typinf.c 2004-10-02 19:19:31.000000000 +0200 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #include #include @@ -28,6 +34,7 @@ #include "aggregate.h" #include +#ifndef IN_GCC #include "cc.h" #include "global.h" #include "oper.h" @@ -37,6 +44,10 @@ #include "cgcv.h" #include "outbuf.h" #include "irstate.h" +#else +#include "symbol.h" +#include "dt.h" +#endif /******************************************* * Get a canonicalized form of the TypeInfo for use with the internal Binary files dmd-0.102/src/phobos/etc/c/recls/recls.lib and gdc-0.8/d/phobos/etc/c/recls/recls.lib differ diff -uNr dmd-0.102/src/phobos/etc/c/stlsoft/unixstl_glob_sequence.h gdc-0.8/d/phobos/etc/c/stlsoft/unixstl_glob_sequence.h --- dmd-0.102/src/phobos/etc/c/stlsoft/unixstl_glob_sequence.h 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/etc/c/stlsoft/unixstl_glob_sequence.h 2004-10-02 19:19:32.000000000 +0200 @@ -56,6 +56,12 @@ * * ////////////////////////////////////////////////////////////////////////// */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef _INCL_UNIXSTL_H_UNIXSTL_GLOB_SEQUENCE #define _INCL_UNIXSTL_H_UNIXSTL_GLOB_SEQUENCE @@ -82,6 +88,7 @@ #endif /* !_STLSOFT_INCL_H_STLSOFT_ITERATOR */ #include #include +#include #include /* ///////////////////////////////////////////////////////////////////////////// @@ -364,7 +371,11 @@ if((m_flags & (directories | files)) == directories) { +#ifdef GLOB_ONLYDIR glob_flags |= GLOB_ONLYDIR; +#else +#define UNIXSTL_GLOB_SEQUENCE_ULTRA_CAUTIOUS +#endif } if(0 == glob(pattern, glob_flags, NULL, &m_gl)) @@ -416,11 +427,15 @@ // We should be able to trust glob() to return only directories when // asked, so we assume the following only needs to be done when // have asked for files alone +#ifdef GLOB_ONLYDIR #ifdef UNIXSTL_GLOB_SEQUENCE_ULTRA_CAUTIOUS if((m_flags & (directories | files)) != (directories | files)) #else /* ? UNIXSTL_GLOB_SEQUENCE_ULTRA_CAUTIOUS */ if((m_flags & (directories | files)) == files) #endif /* UNIXSTL_GLOB_SEQUENCE_ULTRA_CAUTIOUS */ +#else + if (1) +#endif { char_type **begin = base; char_type **end = begin + cItems; diff -uNr dmd-0.102/src/phobos/etc/c/zlib/adler32.c gdc-0.8/d/phobos/etc/c/zlib/adler32.c --- dmd-0.102/src/phobos/etc/c/zlib/adler32.c 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/etc/c/zlib/adler32.c 2004-09-29 04:26:32.000000000 +0200 @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id$ */ +/* @(#) $Id: adler32.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #define ZLIB_INTERNAL #include "zlib.h" diff -uNr dmd-0.102/src/phobos/etc/c/zlib/ChangeLog gdc-0.8/d/phobos/etc/c/zlib/ChangeLog --- dmd-0.102/src/phobos/etc/c/zlib/ChangeLog 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/etc/c/zlib/ChangeLog 2004-09-29 04:26:32.000000000 +0200 @@ -466,7 +466,7 @@ - use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) - added makelcc.bat for lcc-win32 (Tom St Denis) - in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) -- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. +- Avoid expanded $Id: ChangeLog,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. - check for unistd.h in configure (for off_t) - remove useless check parameter in inflate_blocks_free - avoid useless assignment of s->check to itself in inflate_blocks_new diff -uNr dmd-0.102/src/phobos/etc/c/zlib/compress.c gdc-0.8/d/phobos/etc/c/zlib/compress.c --- dmd-0.102/src/phobos/etc/c/zlib/compress.c 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/etc/c/zlib/compress.c 2004-09-29 04:26:32.000000000 +0200 @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id$ */ +/* @(#) $Id: compress.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #define ZLIB_INTERNAL #include "zlib.h" diff -uNr dmd-0.102/src/phobos/etc/c/zlib/crc32.c gdc-0.8/d/phobos/etc/c/zlib/crc32.c --- dmd-0.102/src/phobos/etc/c/zlib/crc32.c 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/etc/c/zlib/crc32.c 2004-09-29 04:26:32.000000000 +0200 @@ -9,7 +9,7 @@ * of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. */ -/* @(#) $Id$ */ +/* @(#) $Id: crc32.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #ifdef MAKECRCH # include diff -uNr dmd-0.102/src/phobos/etc/c/zlib/deflate.c gdc-0.8/d/phobos/etc/c/zlib/deflate.c --- dmd-0.102/src/phobos/etc/c/zlib/deflate.c 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/etc/c/zlib/deflate.c 2004-09-29 04:26:32.000000000 +0200 @@ -47,7 +47,7 @@ * */ -/* @(#) $Id$ */ +/* @(#) $Id: deflate.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #include "deflate.h" diff -uNr dmd-0.102/src/phobos/etc/c/zlib/deflate.h gdc-0.8/d/phobos/etc/c/zlib/deflate.h --- dmd-0.102/src/phobos/etc/c/zlib/deflate.h 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/etc/c/zlib/deflate.h 2004-09-29 04:26:32.000000000 +0200 @@ -8,7 +8,7 @@ subject to change. Applications should only use zlib.h. */ -/* @(#) $Id$ */ +/* @(#) $Id: deflate.h,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #ifndef DEFLATE_H #define DEFLATE_H diff -uNr dmd-0.102/src/phobos/etc/c/zlib/example.c gdc-0.8/d/phobos/etc/c/zlib/example.c --- dmd-0.102/src/phobos/etc/c/zlib/example.c 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/etc/c/zlib/example.c 2004-09-29 04:26:32.000000000 +0200 @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id$ */ +/* @(#) $Id: example.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #include #include "zlib.h" diff -uNr dmd-0.102/src/phobos/etc/c/zlib/gzio.c gdc-0.8/d/phobos/etc/c/zlib/gzio.c --- dmd-0.102/src/phobos/etc/c/zlib/gzio.c 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/etc/c/zlib/gzio.c 2004-09-29 04:26:32.000000000 +0200 @@ -5,7 +5,7 @@ * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. */ -/* @(#) $Id$ */ +/* @(#) $Id: gzio.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #include diff -uNr dmd-0.102/src/phobos/etc/c/zlib/minigzip.c gdc-0.8/d/phobos/etc/c/zlib/minigzip.c --- dmd-0.102/src/phobos/etc/c/zlib/minigzip.c 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/etc/c/zlib/minigzip.c 2004-09-29 04:26:32.000000000 +0200 @@ -13,7 +13,7 @@ * or in pipe mode. */ -/* @(#) $Id$ */ +/* @(#) $Id: minigzip.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #include #include "zlib.h" diff -uNr dmd-0.102/src/phobos/etc/c/zlib/trees.c gdc-0.8/d/phobos/etc/c/zlib/trees.c --- dmd-0.102/src/phobos/etc/c/zlib/trees.c 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/etc/c/zlib/trees.c 2004-09-29 04:26:32.000000000 +0200 @@ -29,7 +29,7 @@ * Addison-Wesley, 1983. ISBN 0-201-06672-6. */ -/* @(#) $Id$ */ +/* @(#) $Id: trees.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ /* #define GEN_TREES_H */ diff -uNr dmd-0.102/src/phobos/etc/c/zlib/uncompr.c gdc-0.8/d/phobos/etc/c/zlib/uncompr.c --- dmd-0.102/src/phobos/etc/c/zlib/uncompr.c 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/etc/c/zlib/uncompr.c 2004-09-29 04:26:32.000000000 +0200 @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id$ */ +/* @(#) $Id: uncompr.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #define ZLIB_INTERNAL #include "zlib.h" diff -uNr dmd-0.102/src/phobos/etc/c/zlib/zconf.h gdc-0.8/d/phobos/etc/c/zlib/zconf.h --- dmd-0.102/src/phobos/etc/c/zlib/zconf.h 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/etc/c/zlib/zconf.h 2004-09-29 04:26:32.000000000 +0200 @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id$ */ +/* @(#) $Id: zconf.h,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #ifndef ZCONF_H #define ZCONF_H diff -uNr dmd-0.102/src/phobos/etc/c/zlib/zconf.in.h gdc-0.8/d/phobos/etc/c/zlib/zconf.in.h --- dmd-0.102/src/phobos/etc/c/zlib/zconf.in.h 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/etc/c/zlib/zconf.in.h 2004-09-29 04:19:34.000000000 +0200 @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id$ */ +/* @(#) $Id: zconf.in.h,v 1.1 2004/09/29 02:19:34 davidfriedman Exp $ */ #ifndef ZCONF_H #define ZCONF_H Binary files dmd-0.102/src/phobos/etc/c/zlib/zlib.lib and gdc-0.8/d/phobos/etc/c/zlib/zlib.lib differ diff -uNr dmd-0.102/src/phobos/etc/c/zlib/zutil.c gdc-0.8/d/phobos/etc/c/zlib/zutil.c --- dmd-0.102/src/phobos/etc/c/zlib/zutil.c 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/etc/c/zlib/zutil.c 2004-09-29 04:26:32.000000000 +0200 @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id$ */ +/* @(#) $Id: zutil.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #include "zutil.h" diff -uNr dmd-0.102/src/phobos/etc/c/zlib/zutil.h gdc-0.8/d/phobos/etc/c/zlib/zutil.h --- dmd-0.102/src/phobos/etc/c/zlib/zutil.h 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/etc/c/zlib/zutil.h 2004-09-29 04:26:32.000000000 +0200 @@ -8,7 +8,7 @@ subject to change. Applications should only use zlib.h. */ -/* @(#) $Id$ */ +/* @(#) $Id: zutil.h,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #ifndef ZUTIL_H #define ZUTIL_H diff -uNr dmd-0.102/src/phobos/frag-ac.in gdc-0.8/d/phobos/frag-ac.in --- dmd-0.102/src/phobos/frag-ac.in 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.8/d/phobos/frag-ac.in 2004-04-18 04:14:33.000000000 +0200 @@ -0,0 +1,7 @@ +// frags-ac.in... + +@DCFG_LONG_DOUBLE_FUNCS@ + +@DCFG_SQRTF@ + +// ...frags-ac.in diff -uNr dmd-0.102/src/phobos/internal/aaA.d gdc-0.8/d/phobos/internal/aaA.d --- dmd-0.102/src/phobos/internal/aaA.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/internal/aaA.d 2004-10-02 19:19:32.000000000 +0200 @@ -2,6 +2,12 @@ // Copyright (c) 2000-2003 by Digital Mars // Written by Walter Bright +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + import std.c.stdio; import std.c.stdlib; import std.string; @@ -161,6 +167,16 @@ body { void *pkey = cast(void *)(&valuesize + 1); + version (BigEndian) + { + switch(keyti.tsize()) { + case 1: pkey = cast(byte*)pkey + 3; break; + case 2: pkey = cast(byte*)pkey + 2; break; + default: + ; + } + } + uint key_hash; uint i; aaA *e; @@ -223,6 +239,16 @@ body { void *pkey = cast(void *)(&keyti + 1); + version (BigEndian) + { + switch(keyti.tsize()) { + case 1: pkey = cast(byte*)pkey + 3; break; + case 2: pkey = cast(byte*)pkey + 2; break; + default: + ; + } + } + uint key_hash; uint i; aaA *e; @@ -263,6 +289,16 @@ void _aaDel(aaA*[] aa, TypeInfo keyti, ...) { void *pkey = cast(void *)(&keyti + 1); + version (BigEndian) + { + switch(keyti.tsize()) { + case 1: pkey = cast(byte*)pkey + 3; break; + case 2: pkey = cast(byte*)pkey + 2; break; + default: + ; + } + } + uint key_hash; uint i; aaA *e; @@ -326,7 +362,7 @@ * Produce array of v byte values from aa. */ -long _aaValues(aaA*[] aa, uint k, uint v) +Array _aaValues(aaA*[] aa, uint k, uint v) { uint resi; Array a; @@ -340,7 +376,7 @@ _aaValues_x(aa[i], a.ptr, resi, k, v); } assert(resi == a.length); - return *cast(long*)(&a); + return a; } void _aaValues_x(aaA *e, void *ptr, inout uint resi, uint k, uint v) @@ -446,7 +482,7 @@ * Produce array of N byte keys from aa. */ -long _aaKeys(aaA*[] aa, uint n) +Array _aaKeys(aaA*[] aa, uint n) { uint len; byte[] res; @@ -466,7 +502,7 @@ Array a; a.length = len; a.ptr = res; - return *cast(long*)(&a); + return a; } private diff -uNr dmd-0.102/src/phobos/internal/adi.d gdc-0.8/d/phobos/internal/adi.d --- dmd-0.102/src/phobos/internal/adi.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/internal/adi.d 2004-10-02 19:19:32.000000000 +0200 @@ -4,6 +4,12 @@ // www.digitalmars.com // Written by Walter Bright +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + // Dynamic array property support routines //debug=adi; // uncomment to turn on debugging printf's @@ -20,15 +26,163 @@ void *ptr; } +// %% Had to move _adCmpChar to the beginning of the file +// due to a extern/static symbol conflict on darwin... +/*************************************** + * Support for array compare test. + */ + +extern (C) int _adCmpChar(Array a1, Array a2) +{ +version (Asm86) +{ + asm + { naked ; + + push EDI ; + push ESI ; + + mov ESI,a1+4[4+ESP] ; + mov EDI,a2+4[4+ESP] ; + + mov ECX,a1[4+ESP] ; + mov EDX,a2[4+ESP] ; + + cmp ECX,EDX ; + jb GotLength ; + + mov ECX,EDX ; + +GotLength: + cmp ECX,4 ; + jb DoBytes ; + + // Do alignment if neither is dword aligned + test ESI,3 ; + jz Aligned ; + + test EDI,3 ; + jz Aligned ; +DoAlign: + mov AL,[ESI] ; //align ESI to dword bounds + mov DL,[EDI] ; + + cmp AL,DL ; + jnz Unequal ; + + inc ESI ; + inc EDI ; + + test ESI,3 ; + + lea ECX,[ECX-1] ; + jnz DoAlign ; +Aligned: + mov EAX,ECX ; + + // do multiple of 4 bytes at a time + + shr ECX,2 ; + jz TryOdd ; + + repe ; + cmpsd ; + + jnz UnequalQuad ; + +TryOdd: + mov ECX,EAX ; +DoBytes: + // if still equal and not end of string, do up to 3 bytes slightly + // slower. + + and ECX,3 ; + jz Equal ; + + repe ; + cmpsb ; + + jnz Unequal ; +Equal: + mov EAX,a1[4+ESP] ; + mov EDX,a2[4+ESP] ; + + sub EAX,EDX ; + pop ESI ; + + pop EDI ; + ret ; + +UnequalQuad: + mov EDX,[EDI-4] ; + mov EAX,[ESI-4] ; + + cmp AL,DL ; + jnz Unequal ; + + cmp AH,DH ; + jnz Unequal ; + + shr EAX,16 ; + + shr EDX,16 ; + + cmp AL,DL ; + jnz Unequal ; + + cmp AH,DH ; +Unequal: + sbb EAX,EAX ; + pop ESI ; + + or EAX,1 ; + pop EDI ; + + ret ; + } +} +else +{ + int len; + int c; + + //printf("adCmpChar()\n"); + len = a1.length; + if (a2.length < len) + len = a2.length; + c = std.string.memcmp(cast(char *)a1.ptr, cast(char *)a2.ptr, len); + if (!c) + c = cast(int)a1.length - cast(int)a2.length; + return c; +} +} + +unittest +{ + debug(adi) printf("array.CmpChar unittest\n"); + + char[] a = "hello"; + + assert(a > "hel"); + assert(a >= "hel"); + assert(a < "helloo"); + assert(a <= "helloo"); + assert(a > "betty"); + assert(a >= "betty"); + assert(a == "hello"); + assert(a <= "hello"); + assert(a >= "hello"); +} + /********************************************** * Support for array.reverse property. */ -extern (C) long _adReverse(Array a, int szelem) +extern (C) Array _adReverse(Array a, int szelem) out (result) { - assert(result is *cast(long*)(&a)); + assert(result is a); } body { @@ -67,7 +221,7 @@ //delete tmp; } } - return *cast(long*)(&a); + return a; } unittest @@ -157,10 +311,10 @@ * Support for array.dup property. */ -extern (C) long _adDup(Array a, int szelem) +extern (C) Array _adDup(Array a, int szelem) out (result) { - assert(memcmp((*cast(Array*)&result).ptr, a.ptr, a.length * szelem) == 0); + assert(memcmp(result.ptr, a.ptr, a.length * szelem) == 0); } body { @@ -171,7 +325,7 @@ r.ptr = cast(void *) new byte[size]; r.length = a.length; memcpy(r.ptr, a.ptr, size); - return *cast(long*)(&r); + return r; } unittest @@ -194,10 +348,10 @@ * Support for array.dup property for bit[]. */ -extern (C) long _adDupBit(Array a) +extern (C) Array _adDupBit(Array a) out (result) { - assert(memcmp((*cast(Array*)(&result)).ptr, a.ptr, (a.length + 7) / 8) == 0); + assert(memcmp(result.ptr, a.ptr, (a.length + 7) / 8) == 0); } body { @@ -207,8 +361,8 @@ size = (a.length + 31) / 32; r.ptr = cast(void *) new uint[size]; r.length = a.length; - memcpy(r.ptr, a.ptr, size); - return *cast(long*)(&r); + memcpy(r.ptr, a.ptr, size * uint.sizeof); + return r; } unittest @@ -281,8 +435,8 @@ if (a1.length != a2.length) return 0; // not equal - byte *p1 = cast(byte*)a1.ptr; - byte *p2 = cast(byte*)a2.ptr; + ubyte *p1 = cast(ubyte*)a1.ptr; + ubyte *p2 = cast(ubyte*)a2.ptr; uint n = a1.length / 8; for (i = 0; i < n; i++) { @@ -357,151 +511,6 @@ assert(a >= "hello"); } -/*************************************** - * Support for array compare test. - */ - -extern (C) int _adCmpChar(Array a1, Array a2) -{ -version (X86) -{ - asm - { naked ; - - push EDI ; - push ESI ; - - mov ESI,a1+4[4+ESP] ; - mov EDI,a2+4[4+ESP] ; - - mov ECX,a1[4+ESP] ; - mov EDX,a2[4+ESP] ; - - cmp ECX,EDX ; - jb GotLength ; - - mov ECX,EDX ; - -GotLength: - cmp ECX,4 ; - jb DoBytes ; - - // Do alignment if neither is dword aligned - test ESI,3 ; - jz Aligned ; - - test EDI,3 ; - jz Aligned ; -DoAlign: - mov AL,[ESI] ; //align ESI to dword bounds - mov DL,[EDI] ; - - cmp AL,DL ; - jnz Unequal ; - - inc ESI ; - inc EDI ; - - test ESI,3 ; - - lea ECX,[ECX-1] ; - jnz DoAlign ; -Aligned: - mov EAX,ECX ; - - // do multiple of 4 bytes at a time - - shr ECX,2 ; - jz TryOdd ; - - repe ; - cmpsd ; - - jnz UnequalQuad ; - -TryOdd: - mov ECX,EAX ; -DoBytes: - // if still equal and not end of string, do up to 3 bytes slightly - // slower. - - and ECX,3 ; - jz Equal ; - - repe ; - cmpsb ; - - jnz Unequal ; -Equal: - mov EAX,a1[4+ESP] ; - mov EDX,a2[4+ESP] ; - - sub EAX,EDX ; - pop ESI ; - - pop EDI ; - ret ; - -UnequalQuad: - mov EDX,[EDI-4] ; - mov EAX,[ESI-4] ; - - cmp AL,DL ; - jnz Unequal ; - - cmp AH,DH ; - jnz Unequal ; - - shr EAX,16 ; - - shr EDX,16 ; - - cmp AL,DL ; - jnz Unequal ; - - cmp AH,DH ; -Unequal: - sbb EAX,EAX ; - pop ESI ; - - or EAX,1 ; - pop EDI ; - - ret ; - } -} -else -{ - int len; - int c; - - //printf("adCmpChar()\n"); - len = a1.length; - if (a2.length < len) - len = a2.length; - c = string.memcmp(cast(char *)a1.ptr, cast(char *)a2.ptr, len); - if (!c) - c = cast(int)a1.length - cast(int)a2.length; - return c; -} -} - -unittest -{ - debug(adi) printf("array.CmpChar unittest\n"); - - char[] a = "hello"; - - assert(a > "hel"); - assert(a >= "hel"); - assert(a < "helloo"); - assert(a <= "helloo"); - assert(a > "betty"); - assert(a >= "betty"); - assert(a == "hello"); - assert(a <= "hello"); - assert(a >= "hello"); -} /*************************************** * Support for array compare test. @@ -527,6 +536,8 @@ { ubyte mask = 1 << j; int c; + // need != 0, otherwise comparison on bit 31 would be wrong... + //c = (int)((p1[i] & mask) != 0) - (int)((p2[i] & mask) != 0); c = cast(int)(p1[i] & mask) - cast(int)(p2[i] & mask); if (c) return c; diff -uNr dmd-0.102/src/phobos/internal/critical.c gdc-0.8/d/phobos/internal/critical.c --- dmd-0.102/src/phobos/internal/critical.c 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/internal/critical.c 2004-10-02 19:19:32.000000000 +0200 @@ -2,6 +2,14 @@ // All Rights Reserved // Written by Walter Bright +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + +#include "config.h" + /* ================================= Win32 ============================ */ #if _WIN32 @@ -73,14 +81,22 @@ /* ================================= linux ============================ */ -#if linux +#if linux || PHOBOS_USE_PTHREADS + #include +#ifndef HAVE_PTHREAD_MUTEX_RECURSIVE +#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP +#endif + + /****************************************** * Enter/exit critical section. */ + + /* We don't initialize critical sections unless we actually need them. * So keep a linked list of the ones we do use, and in the static destructor * code, walk the list and release them. @@ -106,7 +122,7 @@ { dcs->next = dcs_list; dcs_list = dcs; - pthread_mutex_init(&dcs->cs, &_criticals_attr); + pthread_mutex_init(&dcs->cs, & _criticals_attr); } pthread_mutex_unlock(&critical_section.cs); } @@ -122,10 +138,8 @@ { if (!inited) { pthread_mutexattr_init(&_criticals_attr); - pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE_NP); - - // The global critical section doesn't need to be recursive - pthread_mutex_init(&critical_section.cs, 0); + pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&critical_section.cs, 0); // the global critical section doesn't need to be recursive inited = 1; } } diff -uNr dmd-0.102/src/phobos/internal/dmain2.d gdc-0.8/d/phobos/internal/dmain2.d --- dmd-0.102/src/phobos/internal/dmain2.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/internal/dmain2.d 2004-10-02 19:19:32.000000000 +0200 @@ -1,8 +1,19 @@ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + import object; import std.c.stdio; import std.c.stdlib; import std.string; +version (GNU) +{ + private import gcc.config; + private import gcc.gcgcc; +} extern (C) void _STI_monitor_staticctor(); extern (C) void _STD_monitor_staticdtor(); @@ -26,8 +37,21 @@ * function and catch any unhandled exceptions. */ + +version (NoPhobosMain) { +extern (C) int _d_rtl_start(int argc, char **argv) +{ + return true_main(argc, argv); +} +} else { extern (C) int main(int argc, char **argv) { + return true_main(argc, argv); +} +} + +private int true_main(int argc, char **argv) +{ char[] *am; char[][] args; int i; @@ -35,7 +59,18 @@ int myesp; int myebx; - version (linux) + version (GNU) + { + _STI_monitor_staticctor(); + _STI_critical_init(); + gc_init(); + am = cast(char[] *) malloc(argc * (char[]).sizeof); + version (GNU_MustGuessStackBottom) { + setStackBottomGuess(&argv); + } + // %% else version (Win32?) + } + else version (linux) { _STI_monitor_staticctor(); _STI_critical_init(); @@ -75,7 +110,13 @@ _moduleDtor(); gc_term(); - version (linux) + version (GNU) + { + free(am); + _STD_critical_term(); + _STD_monitor_staticdtor(); + } + else version (linux) { free(am); _STD_critical_term(); diff -uNr dmd-0.102/src/phobos/internal/gc/gcbits.d gdc-0.8/d/phobos/internal/gc/gcbits.d --- dmd-0.102/src/phobos/internal/gc/gcbits.d 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/internal/gc/gcbits.d 2004-10-02 19:19:32.000000000 +0200 @@ -4,13 +4,24 @@ // www.digitalmars.com // Written by Walter Bright +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + import std.string; import std.c.stdlib; import std.outofmemory; import std.intrinsic; //version = Asm86; -version = bitops; +version (GNU) { + // bitop intrinsics not implemented yet +} else { + version = bitops; +} + struct GCBits { diff -uNr dmd-0.102/src/phobos/internal/gc/gc.d gdc-0.8/d/phobos/internal/gc/gc.d --- dmd-0.102/src/phobos/internal/gc/gc.d 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/internal/gc/gc.d 2004-10-02 19:19:32.000000000 +0200 @@ -19,8 +19,18 @@ * be misrepresented as being the original software. * o This notice may not be removed or altered from any source * distribution. + * + * Modifications from original software: + * + * 2004-09-24 David Friedman -- Modified to work with the D GCC compiler */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + // Storage allocation @@ -33,7 +43,7 @@ import gcx; import std.outofmemory; import gcstats; -//import std.math; +//import std.math; GC* _gc; @@ -151,34 +161,67 @@ } } -ulong _d_new(uint length, uint size) +Array _d_new(uint length, uint size) { void *p; - ulong result; + Array result; debug(PRINTF) printf("_d_new(length = %d, size = %d)\n", length, size); + /* if (length == 0 || size == 0) result = 0; else + */ + if (length && size) { p = _gc.malloc(length * size); debug(PRINTF) printf(" p = %p\n", p); memset(p, 0, length * size); - result = cast(ulong)length + (cast(ulong)cast(uint)p << 32); + result.length = length; + result.data = cast(byte*)p; + return result; } return result; } +/+ +byte[] _d_new(uint length, uint size) +{ + void *p; + + debug(PRINTF) printf("_d_newarray(length = %d, size = %d)\n", length, size); + if (length && size) + { + p = _gc.malloc(length * size); + debug(PRINTF) printf(" p = %p\n", p); + memset(p, 0, length * size); + return (cast(byte*)p)[0..length]; + } else + return null; +} ++/ -ulong _d_newarrayi(uint length, uint size, ...) +Array _d_newarrayi(uint length, uint size, ...) { void *p; - ulong result; + Array result; debug(PRINTF) printf("_d_newarrayi(length = %d, size = %d)\n", length, size); + /* if (length == 0 || size == 0) result = 0; else + */ + if (length && size) { void* q = cast(void*)(&size + 1); // pointer to initializer + version (BigEndian) + { + switch(size) { + case 1: q = cast(byte*)q + 3; break; + case 2: q = cast(byte*)q + 2; break; + default: + ; + } + } p = _gc.malloc(length * size); debug(PRINTF) printf(" p = %p\n", p); if (size == 1) @@ -190,27 +233,32 @@ memcpy(p + u * size, q, size); } } - result = cast(ulong)length + (cast(ulong)cast(uint)p << 32); + result.length = length; + result.data = cast(byte*)p; } return result; } -ulong _d_newbitarray(uint length, bit value) +Array _d_newbitarray(uint length, bit value) { void *p; - ulong result; + Array result; debug(PRINTF) printf("_d_newbitarray(length = %d, value = %d)\n", length, value); + /* if (length == 0) result = 0; else - { uint size = (length + 7) >> 3; // number of bytes + */ + if (length) + { uint size = ((length + 31) >> 5) * 4; // number of bytes ubyte fill = value ? 0xFF : 0; p = _gc.malloc(size); debug(PRINTF) printf(" p = %p\n", p); memset(p, fill, size); - result = cast(ulong)length + (cast(ulong)cast(uint)p << 32); + result.length = length; + result.data = cast(byte*)p; } return result; } @@ -390,7 +438,7 @@ */ extern (C) -long _d_arrayappend(Array *px, byte[] y, uint size) +Array _d_arrayappend(Array *px, byte[] y, uint size) { uint cap = _gc.capacity(px.data); @@ -405,8 +453,9 @@ px.data = newdata; } px.length = newlength; - px.data[length * size .. newlength * size] = y[]; - return *cast(long*)px; + //px.data[length * size .. newlength * size] = y[]; + memcpy(px.data + length * size, y, y.length * size); + return *px; } @@ -478,15 +527,28 @@ if (newlength * size > cap) { byte* newdata; - //printf("_d_arrayappendc(%d, %d)\n", size, newlength); - newdata = cast(byte *)_gc.malloc(newCapacity(newlength, size)); + //printf("_d_arrayappendc(%d, %d)\n", size, newlength); + newdata = cast(byte *)_gc.malloc(newCapacity(newlength, size)); memcpy(newdata, x, length * size); (cast(void **)(&x))[1] = newdata; } byte *argp = cast(byte *)(&size + 1); *cast(int *)&x = newlength; - (cast(byte *)x)[length * size .. newlength * size] = argp[0 .. size]; + version (LittleEndian) { + (cast(byte *)x)[length * size .. newlength * size] = argp[0 .. size]; + } else { + switch (size) { + case 1: + (cast(byte*)x)[length] = *(argp+3); + break; + case 2: + (cast(short*)x)[length] = *cast(short*)(argp+2); + break; + default: + (cast(byte *)x)[length * size .. newlength * size] = argp[0 .. size]; + } + } return x; /+ @@ -502,7 +564,7 @@ //printf("*argp = %llx\n", *cast(long *)argp); memcpy(&a[x.length * size], argp, size); //printf("a[0] = %llx\n", *cast(long *)&a[0]); - *cast(int *)&a = length; // jam length + *cast(int *)&a = length; // jam length //printf("a[0] = %llx\n", *cast(long *)&a[0]); x = a; return a; diff -uNr dmd-0.102/src/phobos/internal/gc/gcx.d gdc-0.8/d/phobos/internal/gc/gcx.d --- dmd-0.102/src/phobos/internal/gc/gcx.d 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/internal/gc/gcx.d 2004-10-23 22:44:51.000000000 +0200 @@ -4,6 +4,12 @@ // Written by Walter Bright // www.digitalmars.com +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + // D Garbage Collector implementation /************** Debugging ***************************/ @@ -40,12 +46,20 @@ { import win32; } - -version (linux) +else version (GNU) +{ + private import gcc.gcgcc; + private import gcc.builtins; +} +else version (linux) { import gclinux; } +version (BigEndian) + private import std.intrinsic; + + version (MULTI_THREADED) { @@ -173,7 +187,12 @@ { setStackBottom(win32.os_query_stackBottom()); } - version (linux) + else version (GNU) + { + setStackBottom(gcc.gcgcc.os_query_stackBottom()); + gcc.gcgcc.gc_init_extra(); + } + else version (linux) { setStackBottom(gclinux.os_query_stackBottom()); } @@ -509,7 +528,13 @@ //debug(PRINTF) printf("+GC.scanStaticData()\n"); os_query_staticdataseg(&pbot, &nbytes); ptop = pbot + nbytes; - addRange(pbot, ptop); + version (GNU) { + if (pbot) { + addRange(pbot, ptop); + } + } else { + addRange(pbot, ptop); + } //debug(PRINTF) printf("-GC.scanStaticData()\n"); } @@ -896,7 +921,7 @@ void addRange(void *pbot, void *ptop) { - debug(PRINTF) printf("Thread %x ", pthread_self()); + debug(THREADINVARIANT) { debug(PRINTF) printf("Thread %x ", pthread_self()); } debug(PRINTF) printf("%x.Gcx::addRange(%x, %x), nranges = %d\n", this, pbot, ptop, nranges); if (nranges == rangedim) { @@ -920,7 +945,7 @@ void removeRange(void *pbot) { - debug(PRINTF) printf("Thread %x ", pthread_self()); + debug(THREADINVARIANT) { debug(PRINTF) printf("Thread %x ", pthread_self()); } debug(PRINTF) printf("%x.Gcx.removeRange(%x), nranges = %d\n", this, pbot, nranges); for (uint i = nranges; i--;) { @@ -1317,15 +1342,30 @@ // get put on the stack so they'll be scanned void *sp; uint result; - asm + version (GNU) { - pushad ; - mov sp[EBP],ESP ; + __builtin_unwind_init(); + sp = & sp; + } + else + { + asm + { + pushad ; + mov sp[EBP],ESP ; + } } result = fullcollect(sp); - asm + version (GNU) + { + // nothing to do + } + else { - popad ; + asm + { + popad ; + } } return result; } @@ -1394,7 +1434,18 @@ mark(cast(void *)context.Esp, t.stackBottom); mark(&context.Edi, &context.Eip); } - version (linux) + version (GNU) + { + if (t.isSelf()) + t.stackTop = Thread.getESP(); + + //%%fry printf("top=%08x bot=%08x ext=%08x\n", t.stackTop, t.stackBottom, Thread.getESP());//%%try + version (STACKGROWSDOWN) + mark(t.stackTop, t.stackBottom); + else + mark(t.stackBottom, t.stackTop); + } + else version (linux) { // The registers are already stored in the stack //printf("Thread: ESP = x%x, stackBottom = x%x, isSelf = %d\n", Thread.getESP(), t.stackBottom, t.isSelf()); @@ -1465,6 +1516,8 @@ *b = 0; o = pool.baseAddr + (b - bbase) * 32 * 16; + version (BigEndian) + bitm = bswap(bitm); if (!(bitm & 0xFFFF)) { bitm >>= 16; diff -uNr dmd-0.102/src/phobos/internal/memset.d gdc-0.8/d/phobos/internal/memset.d --- dmd-0.102/src/phobos/internal/memset.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/internal/memset.d 2004-10-02 19:19:32.000000000 +0200 @@ -1,3 +1,8 @@ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ extern (C) { @@ -19,7 +24,7 @@ int *_memset32(int *p, int value, int count) { -version (X86) +version (Asm86) { asm { diff -uNr dmd-0.102/src/phobos/internal/monitor.c gdc-0.8/d/phobos/internal/monitor.c --- dmd-0.102/src/phobos/internal/monitor.c 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/internal/monitor.c 2004-10-02 19:19:32.000000000 +0200 @@ -1,8 +1,17 @@ + + // Copyright (c) 2000-2004 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + +#include "config.h" #include @@ -87,14 +96,17 @@ /* =============================== linux ============================ */ -#if linux - -// Includes attribute fixes from David Friedman's GDC port +// needs to be else.. +#if linux || PHOBOS_USE_PTHREADS #include #include "mars.h" +#ifndef HAVE_PTHREAD_MUTEX_RECURSIVE +#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP +#endif + static pthread_mutex_t _monitor_critsec; static pthread_mutexattr_t _monitors_attr; static volatile int inited; @@ -102,10 +114,9 @@ void _STI_monitor_staticctor() { if (!inited) - { - pthread_mutexattr_init(&_monitors_attr); - pthread_mutexattr_settype(&_monitors_attr, PTHREAD_MUTEX_RECURSIVE_NP); - pthread_mutex_init(&_monitor_critsec, 0); + { pthread_mutexattr_init(&_monitors_attr); + pthread_mutexattr_settype(&_monitors_attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&_monitor_critsec, 0); // the global critical section doesn't need to be recursive inited = 1; } } diff -uNr dmd-0.102/src/phobos/internal/qsort.d gdc-0.8/d/phobos/internal/qsort.d --- dmd-0.102/src/phobos/internal/qsort.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/internal/qsort.d 2004-10-02 19:19:32.000000000 +0200 @@ -9,6 +9,12 @@ Denver, Colorado) public domain version */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + /* ** Sorts an array starting at base, of length nbr_elements, each @@ -43,7 +49,7 @@ structures. The default value is optimized for a high cost for compares. */ -extern (C) long _adSort(Array a, TypeInfo ti) +extern (C) Array _adSort(Array a, TypeInfo ti) { byte* base; byte*[40] stack; // stack @@ -123,7 +129,7 @@ limit = sp[1]; } else // else stack empty, all done - return *cast(long*)(&a); + return a; } } diff -uNr dmd-0.102/src/phobos/libphobos.spec.in gdc-0.8/d/phobos/libphobos.spec.in --- dmd-0.102/src/phobos/libphobos.spec.in 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.8/d/phobos/libphobos.spec.in 2004-04-23 06:14:12.000000000 +0200 @@ -0,0 +1,7 @@ +# +# This spec file is read by gdc when linking. +# It is used to specify the standard libraries we need in order +# to link with libphobos. +# +%rename lib liborig +*lib: @LIBS@ %(liborig) diff -uNr dmd-0.102/src/phobos/Makefile.in gdc-0.8/d/phobos/Makefile.in --- dmd-0.102/src/phobos/Makefile.in 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.8/d/phobos/Makefile.in 2004-10-23 22:44:51.000000000 +0200 @@ -0,0 +1,191 @@ +# GDC -- D front-end for GCC +# Copyright (C) 2004 David Friedman +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +AR = @AR@ +RANLIB = @RANLIB@ + +CFLAGS=@CFLAGS@ @DEFS@ -I etc/c/stlsoft -I . + +# Because parts of Phobos are generated (and are in flux), we need +# to prevent this build from getting tripped up on an already installed +# version. Add -nostdinc to handle this. +DFLAGS=@DFLAGS@ -nostdinc + +# Not used since it goes into libphobos.spec +LIBS=@LIBS@ +CC=@CC@ +DMD=@DMD@ + +# For recls +CXXFLAGS=@CXXFLAGS@ @DEFS@ -I $(srcdir)/etc/c/stlsoft -fno-access-control -fno-exceptions + +srcdir=@srcdir@ +VPATH = @srcdir@ + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +all: libphobos.a + +%.o : %.c + $(CC) -o $@ $(CFLAGS) -c $< + +%.o : %.d + $(DMD) -o $@ $(DFLAGS) -I $(srcdir) -I $(srcdir)/internal/gc -c $< + +Makefile: Makefile.in + ./config.status + +unittest: unittest.o libphobos.a + $(DMD) -o $@ $(DFLAGS) unittest.o -L./ + +TI=ti_AC.o ti_Aa.o ti_Adchar.o ti_Ag.o ti_Aint.o ti_Along.o ti_Ashort.o \ + ti_Aubyte.o ti_Auint.o ti_Aulong.o ti_Aushort.o ti_Awchar.o ti_C.o \ + ti_bit.o ti_byte.o ti_cdouble.o ti_cfloat.o ti_char.o ti_creal.o \ + ti_dchar.o ti_delegate.o ti_double.o ti_float.o ti_idouble.o ti_ifloat.o \ + ti_int.o ti_ireal.o ti_long.o ti_ptr.o ti_real.o ti_short.o ti_ubyte.o \ + ti_uint.o ti_ulong.o ti_ushort.o ti_wchar.o + +INIT_MAIN_OBJ=internal/dmain2.o +INIT_NOMAIN_OBJ=internal/dnomain2.o + +MAIN_OBJS=std/asserterror.o internal/switch.o internal/complex.o gcstats.o \ + internal/critical.o internal/object.o internal/monitor.o internal/arraycat.o internal/invariant.o \ + std/outofmemory.o internal/aaA.o internal/adi.o internal/aApply.o std/file.o \ + std/compiler.o std/system.o std/moduleinit.o std/md5.o std/base64.o \ + internal/cast.o std/path.o std/string.o internal/memset.o std/math.o std/mmfile.o \ + std/outbuffer.o std/ctype.o std/regexp.o std/random.o \ + std/stream.o std/switcherr.o std/array.o std/gc.o \ + internal/qsort.o std/thread.o internal/obj.o std/utf.o std/uri.o \ + crc32.o std/conv.o internal/arraycast.o errno.o \ + std/process.o std/syserror.o \ + std/socket.o std/socketstream.o std/c/stdarg.o std/stdio.o std/format.o \ + std/perf.o \ + $(subst ti_,std/typeinfo/ti_,$(TI)) \ + std/date.o std/dateparse.o std/math2.o etc/c/zlib.o std/zlib.o std/zip.o std/recls.o + + +ZLIB_OBJS= etc/c/zlib/adler32.o etc/c/zlib/compress.o \ + etc/c/zlib/crc32.o etc/c/zlib/gzio.o \ + etc/c/zlib/uncompr.o etc/c/zlib/deflate.o \ + etc/c/zlib/trees.o etc/c/zlib/zutil.o \ + etc/c/zlib/inflate.o etc/c/zlib/infback.o \ + etc/c/zlib/inftrees.o etc/c/zlib/inffast.o + +RECLS_OBJS=etc/c/recls/recls_api.o \ + etc/c/recls/recls_fileinfo.o \ + etc/c/recls/recls_internal.o \ + etc/c/recls/recls_util.o \ + etc/c/recls/recls_api_unix.o \ + etc/c/recls/recls_fileinfo_unix.o \ + etc/c/recls/recls_util_unix.o + +GC_OBJS= internal/gc/gc.o internal/gc/gcx.o \ + internal/gc/gcbits.o +# GC_OBJS += gcc/gcgcc.o +GC_OBJS += @D_GC_MODULE@ + +GCC_OBJS = gcc/config.o gcc/unwind.o gcc/deh.o gcc/threadsem.o \ + std/c/dirent.o gcc/cbridge_time.o gcc/cbridge_fdset.o + +# std.c.linux.linux, std.loader, gcc.cbridge* +D_EXTRA_OBJS=@D_EXTRA_OBJS@ + +# needed until instrinsics are implemented +D_EXTRA_OBJS+=std/intrinsic.o + +# currently just add compatibility for a bug +D_EXTRA_OBJS+=gcc/support.o + +# need frac-ac: frag-ac.in,etc. +CONFIG_D_FRAGMENTS = config/config-head frag-ac frag-gen frag-math config/config-mid config/config-tail + +gen_config1: config/gen_config1.o + $(CC) -o $@ $^ + +frag-gen: gen_config1 + ./gen_config1 > $@ + +gcc/config.d: $(CONFIG_D_FRAGMENTS) + cat $^ > $@ + +gen_math: config/gen_math.o + $(CC) -o $@ $^ +frag-math: gen_math + ./gen_math > $@ + +config/gen_unix.o: config/gen_unix.c config/makestruct.h +gen_unix: config/gen_unix.o + $(CC) -o $@ $^ + +frag-unix: gen_unix + ./gen_unix > $@ + +gcc/configunix.d: config/unix-head frag-unix config/unix-mid + cat $^ > $@ +gcc/configunix.o: gcc/configunix.d gcc/config.d + +boehm-gc/d_os_dep.c: $(srcdir)/boehm-gc/os_dep.c + cp $(srcdir)/boehm-gc/os_dep.c $@ + patch -p0 < $(srcdir)/patch-boehm-gc-os_dep +boehm-gc/d_os_dep.o: boehm-gc/d_os_dep.c + cd boehm-gc && $(MAKE) d_os_dep.o +boehm-gc/dyn_load.o: + cd boehm-gc && $(MAKE) dyn_load.o +boehm-gc/d_init.c: $(srcdir)/gcc/boehm-gc-d_init.c + cp $(srcdir)/gcc/boehm-gc-d_init.c $@ +boehm-gc/d_init.o: boehm-gc/d_init.c + cd boehm-gc && $(MAKE) d_init.o + + +# GCC_OBJS (gcc/config.o) first so I don't have to write more deps +libphobos.a : $(D_EXTRA_OBJS) $(GCC_OBJS) $(INIT_MAIN_OBJ) $(MAIN_OBJS) $(ZLIB_OBJS) $(GC_OBJS) $(RECLS_OBJS) + $(AR) -r $@ $(D_EXTRA_OBJS) $(GCC_OBJS) $(INIT_MAIN_OBJ) $(MAIN_OBJS) $(ZLIB_OBJS) $(GC_OBJS) $(RECLS_OBJS) + $(RANLIB) $@ + +internal/dnomain2.o: internal/dmain2.d + $(DMD) -o $@ $(DFLAGS) -fversion=NoPhobosMain -I internal/gc -c $< + +libphobosnm.a: $(GCC_OBJS) $(INIT_NOMAIN_OBJ) $(MAIN_OBJS) $(ZLIB_OBJS) $(GC_OBJS) $(RECLS_OBJS) $(D_EXTRA_OBJS) + $(AR) -r $@ $(GCC_OBJS) $(INIT_NOMAIN_OBJ) $(MAIN_OBJS) $(ZLIB_OBJS) $(GC_OBJS) $(RECLS_OBJS) $(D_EXTRA_OBJS) + $(RANLIB) $@ + +install: gcc/config.d libphobos.a + rm -r -f $(includedir)/d + mkdir -p $(includedir)/d + cp -p -R $(srcdir)/*.d $(includedir)/d + cp -p -R $(srcdir)/etc $(includedir)/d + cp -p -R $(srcdir)/gcc $(includedir)/d + cp -p -R $(srcdir)/internal $(includedir)/d + cp -p -R $(srcdir)/std $(includedir)/d + cp -p gcc/config.d $(includedir)/d/gcc + if test -f gcc/configunix.d; then cp -p gcc/configunix.d $(includedir)/d/gcc; fi + cp -p phobos-ver-syms $(includedir)/d + cp -p libphobos.a $(libdir) + cp -p libphobos.spec $(libdir) + +clean: + echo 'Removing files...' + rm -f $(GCC_OBJS) $(MAIN_OBJS) $(ZLIB_OBJS) $(GC_OBJS) $(RECLS_OBJS) $(INIT_MAIN_OBJ) $(INIT_NOMAIN_OBJ) $(D_EXTRA_OBJS) + + rm -f unittest.o + rm -f unittest + rm -f config/gen_config1.o config/gen_unix.o config/gen_math.o gen_config1 gen_unix gen_math + rm -f frag-gen gcc/config.d gcc/configunix.d + rm -f libphobos.a diff -uNr dmd-0.102/src/phobos/patch-boehm-gc-os_dep gdc-0.8/d/phobos/patch-boehm-gc-os_dep --- dmd-0.102/src/phobos/patch-boehm-gc-os_dep 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.8/d/phobos/patch-boehm-gc-os_dep 2004-04-18 04:14:33.000000000 +0200 @@ -0,0 +1,21 @@ +*** boehm-gc/os_dep.c Mon Sep 22 16:00:23 2003 +--- boehm-gc/d_os_dep.c Tue Apr 6 18:17:30 2004 +*************** +*** 1448,1453 **** +--- 1448,1456 ---- + # endif /* ! MSWIN32 && ! MSWINCE*/ + # endif /* ! OS2 */ + ++ #define FOR_D_ONLY ++ #ifndef FOR_D_ONLY ++ + /* + * Auxiliary routines for obtaining memory from OS. + */ +*************** +*** 4116,4118 **** +--- 4119,4122 ---- + #endif + + ++ #endif /* FOR_D_ONLY */ diff -uNr dmd-0.102/src/phobos/phobos-ver-syms.in gdc-0.8/d/phobos/phobos-ver-syms.in --- dmd-0.102/src/phobos/phobos-ver-syms.in 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.8/d/phobos/phobos-ver-syms.in 2004-10-18 05:27:20.000000000 +0200 @@ -0,0 +1,10 @@ +@DCFG_UNIX@ +@DCFG_MUST_GUESS_STACK_BOTTOM@ +@DCFG_HAVE_DATA_START_END@ +@DCFG_SEMAPHORE_IMPL@ +@DCFG_GC_BITS@ +@DCFG_TRUNC@ +@DCFG_EXP2_LOG2@ +@DCFG_EXECVPE@ +@DCFG_FWIDE@ +@DCFG_SA_LEN@ diff -uNr dmd-0.102/src/phobos/prepcygwin.sh gdc-0.8/d/phobos/prepcygwin.sh --- dmd-0.102/src/phobos/prepcygwin.sh 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.8/d/phobos/prepcygwin.sh 2004-04-23 06:14:12.000000000 +0200 @@ -0,0 +1,10 @@ +#!/bin/sh +# This is needed because of the way symlinks are implemented in Cygwin +if ! test -f object.d; then + echo "Change to .../d/phobos before running this program" + exit 1 +fi +rm -f boehm-gc +cp -pR ../../../boehm-gc . +cp -p ../../../lt* . +cp -p ../../../config-ml.in . diff -uNr dmd-0.102/src/phobos/std/array.d gdc-0.8/d/phobos/std/array.d --- dmd-0.102/src/phobos/std/array.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/array.d 2004-10-02 19:19:32.000000000 +0200 @@ -1,4 +1,10 @@ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.array; private import std.c.stdio; @@ -9,7 +15,7 @@ uint linnum; char[] filename; - + public: this(char[] filename, uint linnum) { this.linnum = linnum; diff -uNr dmd-0.102/src/phobos/std/c/darwin/darwin.d gdc-0.8/d/phobos/std/c/darwin/darwin.d --- dmd-0.102/src/phobos/std/c/darwin/darwin.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.8/d/phobos/std/c/darwin/darwin.d 2004-10-02 19:19:32.000000000 +0200 @@ -0,0 +1,170 @@ +/* GDC -- D front-end for GCC + Copyright (C) 2004 David Friedman + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +module std.c.darwin.darwin; + +import gcc.configunix; + +/+ +alias int time_t; +alias long off_t; + +enum : int +{ + SIGHUP = 1, + SIGINT = 2, + SIGQUIT = 3, + SIGILL = 4, + SIGTRAP = 5, + SIGABRT = 6, + SIGIOT = SIGABRT, + SIGEMT = 7, + SIGFPE = 8, + SIGKILL = 9, + SIGBUS = 10, + SIGSEGV = 11, + SIGSYS = 12, + SIGPIPE = 13, + SIGALRM = 14, + SIGTERM = 15, + SIGURG = 16, + SIGSTOP = 17, + SIGTSTP = 18, + SIGCONT = 19, + SIGCHLD = 20, + SIGTTIN = 21, + SIGTTOU = 22, + SIGIO = 23, + SIGXCPU = 24, + SIGXFSZ = 25, + SIGVTALRM = 26, + SIGPROF = 27, + SIGWINCH = 28, + SIGINFO = 29, + SIGUSR1 = 30, + SIGUSR2 = 31 +} + +enum +{ + O_RDONLY = 0x0000, + O_WRONLY = 0x0001, + O_RDWR = 0x0002, + O_ACCMODE = 0x0003, + O_NONBLOCK = 0x0004, + O_APPEND = 0x0008, + O_SHLOCK = 0x0010, + O_EXLOCK = 0x0020, + O_ASYNC = 0x0040, + O_FSYNC = 0x0080, + O_NOFOLLOW = 0x0100, + O_CREAT = 0x0200, + O_TRUNC = 0x0400, + O_EXCL = 0x0800 + +} + +struct timespec { + time_t tv_sec; /* seconds */ + int tv_nsec; /* and nanoseconds */ +}; + +struct struct_stat { + int st_dev; /* inode's device */ + uint st_ino; /* inode's number */ + ushort st_mode; /* inode protection mode */ + ushort st_nlink; /* number of hard links */ + uint st_uid; /* user ID of the file's owner */ + uint st_gid; /* group ID of the file's group */ + int st_rdev; /* device type */ + version (None) { // #ifndef _POSIX_SOURCE + timespec st_atimespec; /* time of last access */ + timespec st_mtimespec; /* time of last data modification */ + timespec st_ctimespec; /* time of last file status change */ + } else { + time_t st_atime; /* time of last access */ + int st_atimensec; /* nsec of last access */ + time_t st_mtime; /* time of last data modification */ + int st_mtimensec; /* nsec of last data modification */ + time_t st_ctime; /* time of last file status change */ + int st_ctimensec; /* nsec of last file status change */ + } + off_t st_size; /* file size, in bytes */ + long st_blocks; /* blocks allocated for file */ + uint st_blksize; /* optimal blocksize for I/O */ + uint st_flags; /* user defined flags for file */ + uint st_gen; /* file generation number */ + int st_lspare; + long st_qspare[2]; +}; + +enum : int +{ + S_IFIFO = 0010000, + S_IFCHR = 0020000, + S_IFDIR = 0040000, + S_IFBLK = 0060000, + S_IFREG = 0100000, + S_IFLNK = 0120000, + S_IFSOCK = 0140000, + + S_IFMT = 0170000 +} + +extern (C) +{ + int open(char*, int, ...); + int read(int, void*, size_t); + int write(int, void*, size_t); + int close(int); + off_t lseek(int, off_t, int); + int fstat(int, struct_stat*); + int stat(char*, struct_stat*); + int getErrno(); + int chdir(char*); + int mkdir(char*, int); + int rmdir(char*); + char* getcwd(char*, int); +} + +struct timeval { + int tv_sec; /* seconds */ + int tv_usec; /* and microseconds */ +}; + +struct tm { + int tm_sec; /* seconds after the minute [0-60] */ + int tm_min; /* minutes after the hour [0-59] */ + int tm_hour; /* hours since midnight [0-23] */ + int tm_mday; /* day of the month [1-31] */ + int tm_mon; /* months since January [0-11] */ + int tm_year; /* years since 1900 */ + int tm_wday; /* days since Sunday [0-6] */ + int tm_yday; /* days since January 1 [0-365] */ + int tm_isdst; /* Daylight Savings Time flag */ + int tm_gmtoff; /* offset from CUT in seconds */ + char *tm_zone; /* timezone abbreviation */ +}; + +extern (C) +{ + int gettimeofday(timeval*, void*); + time_t time(time_t*); + tm *localtime(time_t*); +} ++/ diff -uNr dmd-0.102/src/phobos/std/c/dirent.d gdc-0.8/d/phobos/std/c/dirent.d --- dmd-0.102/src/phobos/std/c/dirent.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.8/d/phobos/std/c/dirent.d 2004-10-02 19:19:32.000000000 +0200 @@ -0,0 +1,50 @@ +/* GDC -- D front-end for GCC + Copyright (C) 2004 David Friedman + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +module std.c.dirent; + +private import gcc.config; +private import std.string; + +extern(C) { + +struct dirent { + byte[gcc.config.dirent_d_name_offset] opaque1; + char[gcc.config.dirent_d_name_size] d_name; + byte[gcc.config.dirent_remaining_size] opaque2; +} + +struct DIR { + byte[gcc.config.DIR_struct_size] opaque; +} + +DIR * opendir(char *); +dirent * readdir(DIR *); +void rewinddir(DIR *); +int closedir(DIR *); + +} + +char[] readdirD(DIR * dir) +{ + dirent* ent = readdir(dir); + if (ent) + return toString(ent.d_name); + else + return null; +} diff -uNr dmd-0.102/src/phobos/std/c/linux/linux.d gdc-0.8/d/phobos/std/c/linux/linux.d --- dmd-0.102/src/phobos/std/c/linux/linux.d 2004-09-21 19:15:00.000000000 +0200 +++ gdc-0.8/d/phobos/std/c/linux/linux.d 2004-10-02 19:19:32.000000000 +0200 @@ -4,6 +4,12 @@ * Placed into public domain. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.c.linux.linux; import std.c.linux.linuxextern; @@ -85,7 +91,7 @@ unittest { - assert(struct_stat.size == 88); + assert(struct_stat.sizeof == 88); } enum : int diff -uNr dmd-0.102/src/phobos/std/c/mach/mach.d gdc-0.8/d/phobos/std/c/mach/mach.d --- dmd-0.102/src/phobos/std/c/mach/mach.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.8/d/phobos/std/c/mach/mach.d 2004-10-23 22:44:51.000000000 +0200 @@ -0,0 +1,66 @@ +/* GDC -- D front-end for GCC + Copyright (C) 2004 David Friedman + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +module std.c.mach.mach; + +private import std.c.mach.mach_extern; + +extern(C): + +version (BitsPerWord32) +{ + private alias uint natural_t; +} +else version (BitsPerWord64) +{ + private alias ulong natural_t; +} + +enum { + SYNC_POLICY_FIFO = 0x0, + SYNC_POLICY_FIXED_PRIORITY = 0x1, + SYNC_POLICY_REVERSED = 0x2, + SYNC_POLICY_ORDER_MASK = 0x3, + SYNC_POLICY_LIFO = (SYNC_POLICY_FIFO|SYNC_POLICY_REVERSED) +} + +enum { + KERN_SUCCESS = 0 +} + +alias natural_t semaphore_t; // TODO: natural_t +alias natural_t task_t; // TODO: natural_t +alias natural_t mach_port_t; // TODO: natural_t +alias int kern_return_t; +kern_return_t semaphore_create +( + task_t task, + semaphore_t *semaphore, + int policy, + int value +); +kern_return_t semaphore_destroy +( + task_t task, + semaphore_t semaphore +); +kern_return_t semaphore_signal (semaphore_t semaphore); +kern_return_t semaphore_wait (semaphore_t semaphore); + +// just in case this actually gets defined.. +extern(D) mach_port_t current_task() { return mach_task_self_; } diff -uNr dmd-0.102/src/phobos/std/c/mach/mach_extern.d gdc-0.8/d/phobos/std/c/mach/mach_extern.d --- dmd-0.102/src/phobos/std/c/mach/mach_extern.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.8/d/phobos/std/c/mach/mach_extern.d 2004-10-02 19:19:32.000000000 +0200 @@ -0,0 +1,24 @@ +/* GDC -- D front-end for GCC + Copyright (C) 2004 David Friedman + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +module std.c.mach.mach_extern; + +private import std.c.mach.mach; + +// This probably isn't stable +extern (C) mach_port_t mach_task_self_; diff -uNr dmd-0.102/src/phobos/std/c/math.d gdc-0.8/d/phobos/std/c/math.d --- dmd-0.102/src/phobos/std/c/math.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/c/math.d 2004-10-02 19:19:32.000000000 +0200 @@ -4,68 +4,137 @@ * www.digitalmars.com */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + extern (C): alias float float_t; alias double double_t; -real acosl(real); -real asinl(real); -real atanl(real); -real atan2l(real, real); -real cosl(real); -real sinl(real); -real tanl(real); -real acoshl(real x); -real asinhl(real x); -real atanhl(real x); -real coshl(real); -real sinhl(real); -real tanhl(real); -real expl(real); -real exp2l(real); -real expm1l(real); -real frexpl(real,int *); -int ilogbl(real); -real ldexpl(real, int); -real logl(real); -real log10l(real); -real log1pl(real); -real log2l(real); -real logbl(real); -real modfl(real, real *); -real scalbnl(real, int); -real scalblnl(real, int); -real cbrtl(real); -real fabsl(real); -real hypotl(real, real); -real powl(real, real); -real sqrtl(real); -real erfl(real x); -real erfcl(real x); -real lgammal(real x); -real tgammal(real x); -real ceill(real); -real floorl(real); -real nearbyintl(real); -real rintl(real); -int lrintl(real x); -long llrintl(real x); -real roundl(real); -int lroundl(real x); -long llroundl(real x); -real truncl(real); -real fmodl(real, real); -real remainderl(real, real); -real remquol(real, real, int *); -real copysignl(real, real); -real nanl(char *); -real nextafterl(real, real); -real nexttowardl(real, real); -real fdiml(real, real); -real fmaxl(real, real); -real fminl(real, real); -real fmal(real, real, real); +version (GNU) +{ + private import gcc.config; + // unfortunately, these do not always exist in a library + alias gcc.config.acosl acosl; + alias gcc.config.asinl asinl; + alias gcc.config.atanl atanl; + alias gcc.config.atan2l atan2l; + alias gcc.config.cosl cosl; + alias gcc.config.sinl sinl; + alias gcc.config.tanl tanl; + alias gcc.config.acoshl acoshl; + alias gcc.config.asinhl asinhl; + alias gcc.config.atanhl atanhl; + alias gcc.config.coshl coshl; + alias gcc.config.sinhl sinhl; + alias gcc.config.tanhl tanhl; + alias gcc.config.expl expl; + alias gcc.config.exp2l exp2l; + alias gcc.config.expm1l expm1l; + alias gcc.config.frexpl frexpl; + alias gcc.config.ilogbl ilogbl; + alias gcc.config.ldexpl ldexpl; + alias gcc.config.logl logl; + alias gcc.config.log10l log10l; + alias gcc.config.log1pl log1pl; + alias gcc.config.log2l log2l; + alias gcc.config.logbl logbl; + alias gcc.config.modfl modfl; + alias gcc.config.scalbnl scalbnl; + alias gcc.config.scalblnl scalblnl; + alias gcc.config.cbrtl cbrtl; + alias gcc.config.fabsl fabsl; + alias gcc.config.hypotl hypotl; + alias gcc.config.powl powl; + alias gcc.config.sqrtl sqrtl; + alias gcc.config.erfl erfl; + alias gcc.config.erfcl erfcl; + alias gcc.config.lgammal lgammal; + alias gcc.config.tgammal tgammal; + alias gcc.config.ceill ceill; + alias gcc.config.floorl floorl; + alias gcc.config.nearbyintl nearbyintl; + alias gcc.config.rintl rintl; + alias gcc.config.lrintl lrintl; + alias gcc.config.llrintl llrintl; + alias gcc.config.roundl roundl; + alias gcc.config.lroundl lroundl; + alias gcc.config.llroundl llroundl; + alias gcc.config.truncl truncl; + alias gcc.config.fmodl fmodl; + alias gcc.config.remainderl remainderl; + alias gcc.config.remquol remquol; + alias gcc.config.copysignl copysignl; + alias gcc.config.nanl nanl; + alias gcc.config.nextafterl nextafterl; + alias gcc.config.nexttowardl nexttowardl; + alias gcc.config.fdiml fdiml; + alias gcc.config.fmaxl fmaxl; + alias gcc.config.fminl fminl; + alias gcc.config.fmal fmal; +} else { + real acosl(real); + real asinl(real); + real atanl(real); + real atan2l(real, real); + real cosl(real); + real sinl(real); + real tanl(real); + real acoshl(real x); + real asinhl(real x); + real atanhl(real x); + real coshl(real); + real sinhl(real); + real tanhl(real); + real expl(real); + real exp2l(real); + real expm1l(real); + real frexpl(real,int *); + int ilogbl(real); + real ldexpl(real, int); + real logl(real); + real log10l(real); + real log1pl(real); + real log2l(real); + real logbl(real); + real modfl(real, real *); + real scalbnl(real, int); + real scalblnl(real, int); + real cbrtl(real); + real fabsl(real); + real hypotl(real, real); + real powl(real, real); + real sqrtl(real); + real erfl(real x); + real erfcl(real x); + real lgammal(real x); + real tgammal(real x); + real ceill(real); + real floorl(real); + real nearbyintl(real); + real rintl(real); + int lrintl(real x); + long llrintl(real x); + real roundl(real); + int lroundl(real x); + long llroundl(real x); + real truncl(real); + real fmodl(real, real); + real remainderl(real, real); + real remquol(real, real, int *); + real copysignl(real, real); + real nanl(char *); + real nextafterl(real, real); + real nexttowardl(real, real); + real fdiml(real, real); + real fmaxl(real, real); + real fminl(real, real); + real fmal(real, real, real); +} int isgreater(real x, real y) { return !(x !> y); } diff -uNr dmd-0.102/src/phobos/std/c/stdarg.d gdc-0.8/d/phobos/std/c/stdarg.d --- dmd-0.102/src/phobos/std/c/stdarg.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/c/stdarg.d 2004-10-02 19:19:32.000000000 +0200 @@ -4,8 +4,23 @@ * Written by Hauke Duden and Walter Bright */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.c.stdarg; +version (GNU) { + private import gcc.builtins; + alias __builtin_va_list va_list; + alias __builtin_va_start va_start; + alias __builtin_va_end va_end; + + // the va_arg function is magically interpreted by the compiler +} else { + alias void* va_list; template va_start(T) @@ -16,6 +31,12 @@ } } +void va_end(va_list ap) +{ +} + +} + template va_arg(T) { T va_arg(inout va_list ap) @@ -26,6 +47,3 @@ } } -void va_end(va_list ap) -{ -} diff -uNr dmd-0.102/src/phobos/std/c/stdio.d gdc-0.8/d/phobos/std/c/stdio.d --- dmd-0.102/src/phobos/std/c/stdio.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/c/stdio.d 2004-10-02 19:19:32.000000000 +0200 @@ -5,6 +5,12 @@ * Placed into Public Domain. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.c.stdio; @@ -26,7 +32,16 @@ const wchar WEOF = 0xFFFF; } -version (linux) +version (GNU) { + private import gcc.builtins; + private import gcc.config; + alias gcc.config.EOF EOF; + alias gcc.config.FOPEN_MAX FOPEN_MAX; + alias gcc.config.FILENAME_MAX FILENAME_MAX; + alias gcc.config.TMP_MAX TMP_MAX; + alias gcc.config.L_tmpnam L_tmpnam; +} +else version (linux) { const int EOF = -1; const int FOPEN_MAX = 16; @@ -74,6 +89,10 @@ char[1] _shortbuf; void* _lock; } + else version (GNU) { + byte[gcc.config.FILE_struct_size] opaque; + } + } alias _iobuf FILE; @@ -136,7 +155,13 @@ const FILE *stdprn = &_iob[4]; } -version (linux) +version (GNU) +{ + const FILE * stdin = cast(FILE *) gcc.config.stdin; + const FILE * stdout = cast(FILE *) gcc.config.stdout; + const FILE * stderr = cast(FILE *) gcc.config.stderr; +} +else version (linux) { FILE *stdin; FILE *stdout; @@ -212,7 +237,20 @@ int _vsnprintf(char *,size_t,char *,va_list); } -version (linux) +version (GNU) +{ + alias gcc.config.ferror ferror; + alias gcc.config.feof feof; + alias gcc.config.clearerr clearerr; + alias gcc.config.rewind rewind; + alias gcc.config._bufsize _bufsize; + alias gcc.config.fileno fileno; + alias gcc.config.Csnprintf snprintf; + alias gcc.config.Cvsnprintf vsnprintf; + alias gcc.config.Csnprintf _snprintf; + alias gcc.config.Cvsnprintf _vsnprintf; +} +else version (linux) { int ferror(FILE *fp); int feof(FILE *fp); diff -uNr dmd-0.102/src/phobos/std/c/stdlib.d gdc-0.8/d/phobos/std/c/stdlib.d --- dmd-0.102/src/phobos/std/c/stdlib.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/c/stdlib.d 2004-10-02 19:19:32.000000000 +0200 @@ -1,4 +1,10 @@ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.c.stdlib; extern (C): @@ -19,7 +25,13 @@ void exit(int); void _exit(int); - void *alloca(uint); + version (GNU) + { + private import gcc.builtins; + alias gcc.builtins.__builtin_alloca alloca; + } else { + void *alloca(uint); + } void *calloc(uint, uint); void *malloc(uint); diff -uNr dmd-0.102/src/phobos/std/c/unix.d gdc-0.8/d/phobos/std/c/unix.d --- dmd-0.102/src/phobos/std/c/unix.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.8/d/phobos/std/c/unix.d 2004-10-02 19:19:32.000000000 +0200 @@ -0,0 +1,29 @@ +/* GDC -- D front-end for GCC + Copyright (C) 2004 David Friedman + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +module std.c.unix; + +/* This module imports the unix module for the currect + target system. Currently, all targets can be + handled with the autoconf'd version +*/ + +import gcc.configunix; + +// DMD linux.d has dirent.h declarations +import std.c.dirent; diff -uNr dmd-0.102/src/phobos/std/date.d gdc-0.8/d/phobos/std/date.d --- dmd-0.102/src/phobos/std/date.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/date.d 2004-10-02 19:19:32.000000000 +0200 @@ -4,6 +4,12 @@ // written by Walter Bright // www.digitalmars.com +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.date; private import std.c.stdio; @@ -169,9 +175,9 @@ int Day(d_time t) { - if (t < 0) - t -= msPerDay; // use this if t is not floating point - return cast(int)floor(t / msPerDay); + if (t < 0) + t -= msPerDay; // use this if t is not floating point + return cast(int)floor(t / msPerDay); } int LeapYear(int y) @@ -187,7 +193,7 @@ int DayFromYear(int y) { - return cast(int) (365 * (y - 1970) + + return cast(int) (365 * (y - 1970) + floor((y - 1969.0) / 4) - floor((y - 1901.0) / 100) + floor((y - 1601.0) / 400)); @@ -195,14 +201,14 @@ d_time TimeFromYear(int y) { - return cast(d_time)msPerDay * DayFromYear(y); + return cast(d_time)msPerDay * DayFromYear(y); } int YearFromTime(d_time t) { int y; // Hazard a guess - y = 1970 + cast(int) (t / (365.2425 * msPerDay)); + y = 1970 + cast(int) (t / (365.2425 * msPerDay)); if (TimeFromYear(y) <= t) { @@ -318,7 +324,7 @@ int WeekDay(d_time t) { int w; - w = (cast(int)Day(t) + 4) % 7; + w = (cast(int)Day(t) + 4) % 7; if (w < 0) w += 7; return w; @@ -379,11 +385,11 @@ month = toInteger(month); date = toInteger(date); - y = cast(int)(year + floor(month / 12)); - m = cast(int)dmod(month, 12); + y = cast(int)(year + floor(month / 12)); + m = cast(int)dmod(month, 12); leap = LeapYear(y); - t = TimeFromYear(y) + cast(d_time)mdays[m] * msPerDay; + t = TimeFromYear(y) + cast(d_time)mdays[m] * msPerDay; if (leap && month >= 2) t += msPerDay; @@ -445,7 +451,7 @@ offset = -(LocalTZA + dst); } - mn = cast(int)(offset / msPerMinute); + mn = cast(int)(offset / msPerMinute); hr = mn / 60; mn %= 60; @@ -455,9 +461,9 @@ &daystr[WeekDay(t) * 3], &monstr[MonthFromTime(t) * 3], DateFromTime(t), - cast(int)HourFromTime(t), cast(int)MinFromTime(t), cast(int)SecFromTime(t), + cast(int)HourFromTime(t), cast(int)MinFromTime(t), cast(int)SecFromTime(t), sign, hr, mn, - cast(long)YearFromTime(t)); + cast(long)YearFromTime(t)); // Ensure no buggy buffer overflows //printf("len = %d, buffer.length = %d\n", len, buffer.length); @@ -490,7 +496,7 @@ &daystr[WeekDay(t) * 3], &monstr[MonthFromTime(t) * 3], DateFromTime(t), - cast(long)YearFromTime(t)); + cast(long)YearFromTime(t)); // Ensure no buggy buffer overflows assert(len < buffer.length); @@ -526,14 +532,14 @@ offset = -(LocalTZA + dst); } - mn = cast(int)(offset / msPerMinute); + mn = cast(int)(offset / msPerMinute); hr = mn / 60; mn %= 60; //printf("hr = %d, offset = %g, LocalTZA = %g, dst = %g, + = %g\n", hr, offset, LocalTZA, dst, LocalTZA + dst); len = sprintf(buffer, "%02d:%02d:%02d GMT%c%02d%02d", - cast(int)HourFromTime(t), cast(int)MinFromTime(t), cast(int)SecFromTime(t), + cast(int)HourFromTime(t), cast(int)MinFromTime(t), cast(int)SecFromTime(t), sign, hr, mn); // Ensure no buggy buffer overflows @@ -654,7 +660,7 @@ //printf("bias = %d\n", tzi.Bias); //printf("standardbias = %d\n", tzi.StandardBias); //printf("daylightbias = %d\n", tzi.DaylightBias); - t = -(tzi.Bias + tzi.StandardBias) * cast(d_time)(60 * TicksPerSecond); + t = -(tzi.Bias + tzi.StandardBias) * cast(d_time)(60 * TicksPerSecond); break; default: @@ -711,7 +717,63 @@ } } -version (linux) +version (GNU) +{ + // for now, just copy linux + private import std.c.unix; + + d_time getUTCtime() + { timeval tv; + + if (gettimeofday(&tv, null)) + { // Some error happened - try time() instead + return time(null) * TicksPerSecond; + } + + return tv.tv_sec * cast(d_time)TicksPerSecond + + (tv.tv_usec / (1000000 / cast(d_time)TicksPerSecond)); + } + + private extern (C) time_t _d_gnu_cbridge_tza(); + + d_time getLocalTZA() + { + return - ( _d_gnu_cbridge_tza() * TicksPerSecond ); + /+ + int t; + tm * t_tm; + + time(&t); + t_tm = localtime(&t); // this will set timezone + // %%TODO: handle systems without tm_gmtoff + // %%TODO: configurate on _timezone instead of this.. + version (cygwin) { + return _timzone * TicksPerSecond; + } else { + return -(t_tm.tm_gmtoff * TicksPerSecond); + } + +/ + } + + /* + * Get daylight savings time adjust for time dt. + */ + + int DaylightSavingTA(d_time dt) + { + tm *tmp; + int t; + + t = cast(int) (dt / TicksPerSecond); // BUG: need range check + tmp = localtime(&t); + if (tmp.tm_isdst > 0) + // BUG: Assume daylight savings time is plus one hour. + return 60 * 60 * TicksPerSecond; + + return 0; + } +} +else version (linux) { private import std.c.linux.linux; diff -uNr dmd-0.102/src/phobos/std/file.d gdc-0.8/d/phobos/std/file.d --- dmd-0.102/src/phobos/std/file.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/file.d 2004-10-02 19:19:32.000000000 +0200 @@ -19,8 +19,15 @@ * be misrepresented as being the original software. * o This notice may not be removed or altered from any source * distribution. + * */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.file; private import std.c.stdio; @@ -540,10 +547,29 @@ /* =========================== linux ======================= */ -version (linux) +// else version (GNU) +/* + { + version (Unix) { + private import std.c.unix; + } + } + */ + +version (linux) { + version = Unix; +} + +version (Unix) { + version (GNU) { + private import std.c.unix; + alias std.c.unix unix; + } else version (linux) { + private import std.c.linux.linux; + alias std.c.linux.linux unix; + } -private import std.c.linux.linux; /******************************************** * Read a file. @@ -562,7 +588,7 @@ namez = toStringz(name); //printf("file.read('%s')\n",namez); - fd = std.c.linux.linux.open(namez, O_RDONLY); + fd = unix.open(namez, O_RDONLY); if (fd == -1) { //printf("\topen error, errno = %d\n",getErrno()); @@ -570,7 +596,7 @@ } //printf("\tfile opened\n"); - if (std.c.linux.linux.fstat(fd, &statbuf)) + if (unix.fstat(fd, &statbuf)) { //printf("\tfstat error, errno = %d\n",getErrno()); goto err2; @@ -578,14 +604,14 @@ size = statbuf.st_size; buf = new byte[size]; - numread = std.c.linux.linux.read(fd, cast(char*)buf, size); + numread = unix.read(fd, cast(char*)buf, size); if (numread != size) { //printf("\tread error, errno = %d\n",getErrno()); goto err2; } - if (std.c.linux.linux.close(fd) == -1) + if (unix.close(fd) == -1) { //printf("\tclose error, errno = %d\n",getErrno()); goto err; @@ -594,7 +620,7 @@ return buf; err2: - std.c.linux.linux.close(fd); + unix.close(fd); err: delete buf; @@ -615,21 +641,21 @@ char *namez; namez = toStringz(name); - fd = std.c.linux.linux.open(namez, O_CREAT | O_WRONLY | O_TRUNC, 0660); + fd = unix.open(namez, O_CREAT | O_WRONLY | O_TRUNC, 0660); if (fd == -1) goto err; - numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); + numwritten = unix.write(fd, buffer, buffer.length); if (buffer.length != numwritten) goto err2; - if (std.c.linux.linux.close(fd) == -1) + if (unix.close(fd) == -1) goto err; return; err2: - std.c.linux.linux.close(fd); + unix.close(fd); err: throw new FileException(name, getErrno()); } @@ -646,21 +672,21 @@ char *namez; namez = toStringz(name); - fd = std.c.linux.linux.open(namez, O_APPEND | O_WRONLY | O_CREAT, 0660); + fd = unix.open(namez, O_APPEND | O_WRONLY | O_CREAT, 0660); if (fd == -1) goto err; - numwritten = std.c.linux.linux.write(fd, buffer, buffer.length); + numwritten = unix.write(fd, buffer, buffer.length); if (buffer.length != numwritten) goto err2; - if (std.c.linux.linux.close(fd) == -1) + if (unix.close(fd) == -1) goto err; return; err2: - std.c.linux.linux.close(fd); + unix.close(fd); err: throw new FileException(name, getErrno()); } @@ -704,7 +730,7 @@ namez = toStringz(name); //printf("file.getSize('%s')\n",namez); - fd = std.c.linux.linux.open(namez, O_RDONLY); + fd = unix.open(namez, O_RDONLY); if (fd == -1) { //printf("\topen error, errno = %d\n",getErrno()); @@ -712,14 +738,14 @@ } //printf("\tfile opened\n"); - if (std.c.linux.linux.fstat(fd, &statbuf)) + if (unix.fstat(fd, &statbuf)) { //printf("\tfstat error, errno = %d\n",getErrno()); goto err2; } size = statbuf.st_size; - if (std.c.linux.linux.close(fd) == -1) + if (unix.close(fd) == -1) { //printf("\tclose error, errno = %d\n",getErrno()); goto err; @@ -728,7 +754,7 @@ return size; err2: - std.c.linux.linux.close(fd); + unix.close(fd); err: err1: throw new FileException(name, getErrno()); @@ -745,7 +771,7 @@ char *namez; namez = toStringz(name); - if (std.c.linux.linux.stat(namez, &statbuf)) + if (unix.stat(namez, &statbuf)) { throw new FileException(name, getErrno()); } @@ -763,7 +789,7 @@ char *namez; namez = toStringz(name); - if (std.c.linux.linux.stat(namez, &statbuf)) + if (unix.stat(namez, &statbuf)) { return 0; } @@ -795,7 +821,7 @@ void chdir(char[] pathname) { - if (std.c.linux.linux.chdir(toStringz(pathname))) + if (unix.chdir(toStringz(pathname))) { throw new FileException(pathname, getErrno()); } @@ -807,7 +833,7 @@ void mkdir(char[] pathname) { - if (std.c.linux.linux.mkdir(toStringz(pathname), 0777)) + if (unix.mkdir(toStringz(pathname), 0777)) { throw new FileException(pathname, getErrno()); } @@ -819,7 +845,7 @@ void rmdir(char[] pathname) { - if (std.c.linux.linux.rmdir(toStringz(pathname))) + if (unix.rmdir(toStringz(pathname))) { throw new FileException(pathname, getErrno()); } @@ -832,7 +858,7 @@ char[] getcwd() { char* p; - p = std.c.linux.linux.getcwd(null, 0); + p = unix.getcwd(null, 0); if (!p) { throw new FileException("cannot get cwd", getErrno()); diff -uNr dmd-0.102/src/phobos/std/intrinsic.d gdc-0.8/d/phobos/std/intrinsic.d --- dmd-0.102/src/phobos/std/intrinsic.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/intrinsic.d 2004-10-02 19:19:32.000000000 +0200 @@ -5,11 +5,77 @@ // written by Walter Bright // www.digitalmars.com +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + /* These functions are built-in intrinsics to the compiler. */ module std.intrinsic; +version (GNU) +{ +int bsf(uint v) +{ + uint m = 1; + uint i; + for (i = 0; i < 32; i++,m<<=1) { + if (v&m) + return i; + } + return i; // supposed to be undefined +} +int bsr(uint v) +{ + uint m = 0x80000000; + uint i; + for (i = 32; i ; i--,m>>>=1) { + if (v&m) + return i-1; + } + return i; // supposed to be undefined +} +int bt(uint *p, uint bitnum) +{ + return (*p & (1<>8)|((v&0xFF000000)>>24); +} + +ubyte inp(uint p) { return 0; } +ushort inpw(uint p) { return 0; } +uint inpl(uint p) { return 0; } + +ubyte outp(uint p, ubyte v) { return v; } +ushort outpw(uint p, ushort v) { return v; } +uint outpl(uint p, uint v) { return v; } +} +else +{ int bsf(uint v); int bsr(uint v); int bt(uint *p, uint bitnum); @@ -26,5 +92,6 @@ ubyte outp(uint, ubyte); ushort outpw(uint, ushort); uint outpl(uint, uint); +} diff -uNr dmd-0.102/src/phobos/std/loader.d gdc-0.8/d/phobos/std/loader.d --- dmd-0.102/src/phobos/std/loader.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/loader.d 2004-10-23 22:44:51.000000000 +0200 @@ -56,6 +56,12 @@ * * ////////////////////////////////////////////////////////////////////////// */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, October 2004 (applied patches from Anders F Björklund.) +*/ + /** \file D/std/loader.d This file contains the \c D standard library @@ -93,7 +99,7 @@ alias HMODULE HModule_; } } -else version(Linux) +else version(linux) { extern(C) { @@ -107,6 +113,104 @@ char *dlerror(); } } +else version(darwin) +{ + extern(C) + { + // #include + + struct mach_header + { + uint magic; /* mach magic number identifier */ + uint cputype; /* cpu specifier */ + uint cpusubtype; /* machine specifier */ + uint filetype; /* type of file */ + uint ncmds; /* number of load commands */ + uint sizeofcmds; /* the size of all the load commands */ + uint flags; /* flags */ + } + + /* Constant for the magic field of the mach_header */ + const uint MH_MAGIC = 0xfeedface; // the mach magic number + const uint MH_CIGAM = 0xcefaedfe; // x86 variant + + // #include + + typedef void *NSObjectFileImage; + + typedef void *NSModule; + + typedef void *NSSymbol; + + enum // DYLD_BOOL: uint + { + FALSE, + TRUE + } + alias uint DYLD_BOOL; + + enum // NSObjectFileImageReturnCode: uint + { + NSObjectFileImageFailure, /* for this a message is printed on stderr */ + NSObjectFileImageSuccess, + NSObjectFileImageInappropriateFile, + NSObjectFileImageArch, + NSObjectFileImageFormat, /* for this a message is printed on stderr */ + NSObjectFileImageAccess + } + alias uint NSObjectFileImageReturnCode; + + enum // NSLinkEditErrors: uint + { + NSLinkEditFileAccessError, + NSLinkEditFileFormatError, + NSLinkEditMachResourceError, + NSLinkEditUnixResourceError, + NSLinkEditOtherError, + NSLinkEditWarningError, + NSLinkEditMultiplyDefinedError, + NSLinkEditUndefinedError + } + alias uint NSLinkEditErrors; + + + alias NSModule HModule_; + + NSObjectFileImageReturnCode NSCreateObjectFileImageFromFile(char *pathName, NSObjectFileImage* objectFileImage); + DYLD_BOOL NSDestroyObjectFileImage(NSObjectFileImage objectFileImage); + + mach_header * NSAddImage(char *image_name, uint options); + const uint NSADDIMAGE_OPTION_NONE = 0x0; + const uint NSADDIMAGE_OPTION_RETURN_ON_ERROR = 0x1; + const uint NSADDIMAGE_OPTION_WITH_SEARCHING = 0x2; + const uint NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED = 0x4; + const uint NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME = 0x8; + + NSModule NSLinkModule(NSObjectFileImage objectFileImage, char* moduleName, uint options); + const uint NSLINKMODULE_OPTION_NONE = 0x0; + const uint NSLINKMODULE_OPTION_BINDNOW = 0x01; + const uint NSLINKMODULE_OPTION_PRIVATE = 0x02; + const uint NSLINKMODULE_OPTION_RETURN_ON_ERROR = 0x04; + const uint NSLINKMODULE_OPTION_DONT_CALL_MOD_INIT_ROUTINES = 0x08; + const uint NSLINKMODULE_OPTION_TRAILING_PHYS_NAME = 0x10; + DYLD_BOOL NSUnLinkModule(NSModule module_, uint options); + + void NSLinkEditError(NSLinkEditErrors *c, int *errorNumber, char **fileName, char **errorString); + + DYLD_BOOL NSIsSymbolNameDefined(char *symbolName); + DYLD_BOOL NSIsSymbolNameDefinedInImage(mach_header *image, char *symbolName); + NSSymbol NSLookupAndBindSymbol(char *symbolName); + NSSymbol NSLookupSymbolInModule(NSModule module_, char* symbolName); + NSSymbol NSLookupSymbolInImage(mach_header *image, char *symbolName, uint options); + const uint NSLOOKUPSYMBOLINIMAGE_OPTION_BIND = 0x0; + const uint NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW = 0x1; + const uint NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY = 0x2; + const uint NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR = 0x4; + + void* NSAddressOfSymbol(NSSymbol symbol); + char* NSNameOfSymbol(NSSymbol symbol); + } +} else { const int platform_not_discriminated = 0; @@ -282,7 +386,7 @@ return szFileName[0 .. cch].dup; } } -else version(Linux) +else version(linux) { private class ExeModuleInfo { @@ -471,6 +575,258 @@ return mi.m_name; } } +else version(darwin) +{ + private class ExeModuleInfo + { + public: + int m_cRefs; + HModule_ m_hmod; + char[] m_name; + + this(HModule_ hmod, char[] name) + { + m_cRefs = 1; + m_hmod = hmod; + m_name = name; + } + }; + + private void record_error_() + { + NSLinkEditErrors error; + int errno; + char *fileName; + char *err = null; + + NSLinkEditError(&error, &errno, &fileName, &err); + printf("NSLinkEditError: %d %d - %s %s\n", cast(uint) error, errno, fileName, err); + + s_lastError = (err == null) ? "" : err[0 .. std.string.strlen(err)]; + } + + private int s_init; + private ExeModuleInfo [char[]] s_modules; + private char[] s_lastError; // This is NOT thread-specific + + private int ExeModule_Init_() + { + if(1 == ++s_init) + { + return 0; + } + + return 1; + } + + private void ExeModule_Uninit_() + { + if(0 == --s_init) + { + } + } + + private HXModule ExeModule_Load_(in char[] moduleName) + in + { + assert(null !== moduleName); + } + body + { + ExeModuleInfo mi = s_modules[moduleName]; + + if(null !== mi) + { + return (++mi.m_cRefs, cast(HXModule)mi); + } + else + { + NSModule handle = null; + NSObjectFileImage fileImage = null; + char * filename = toStringz(moduleName); + // printf("DEBUG Trying to load: %s\n", filename); + + NSObjectFileImageReturnCode returnCode = + NSCreateObjectFileImageFromFile(filename, &fileImage); + if(returnCode == NSObjectFileImageSuccess) + { + handle = NSLinkModule(fileImage,filename, + NSLINKMODULE_OPTION_RETURN_ON_ERROR | + NSLINKMODULE_OPTION_PRIVATE | + NSLINKMODULE_OPTION_BINDNOW); + NSDestroyObjectFileImage(fileImage); + } + else if(returnCode == NSObjectFileImageInappropriateFile) + { + NSDestroyObjectFileImage(fileImage); + /* Could be dynamic library rather than a bundle */ + handle = cast(NSModule) NSAddImage(filename, + NSADDIMAGE_OPTION_RETURN_ON_ERROR); + } + else + { + // printf("Failed: %d\n", returnCode); + s_lastError = "NSCreateObjectFileImageFromFile failed"; + return null; + } + + if (handle == null) + { + record_error_(); + + return null; + } + else + { + ExeModuleInfo mi = new ExeModuleInfo(handle, moduleName); + + s_modules[moduleName] = mi; + + return cast(HXModule)mi; + } + } + } + + private HXModule ExeModule_AddRef_(in HXModule hModule) + in + { + assert(null !== hModule); + + ExeModuleInfo mi = cast(ExeModuleInfo)hModule; + + assert(0 < mi.m_cRefs); + assert(null !== mi.m_hmod); + assert(null !== mi.m_name); + assert(null !== s_modules[mi.m_name]); + assert(mi is s_modules[mi.m_name]); + } + body + { + ExeModuleInfo mi = cast(ExeModuleInfo)hModule; + + if(null !== mi) + { + return (++mi.m_cRefs, hModule); + } + else + { + return null; + } + } + + private void ExeModule_Release_(inout HXModule hModule) + in + { + assert(null !== hModule); + + ExeModuleInfo mi = cast(ExeModuleInfo)hModule; + + assert(0 < mi.m_cRefs); + assert(null !== mi.m_hmod); + assert(null !== mi.m_name); + assert(null !== s_modules[mi.m_name]); + assert(mi is s_modules[mi.m_name]); + } + body + { + ExeModuleInfo mi = cast(ExeModuleInfo)hModule; + + if(0 == --mi.m_cRefs) + { + char[] name = mi.m_name; + uint magic; + + magic = (* cast(mach_header *) mi.m_hmod).magic; + if ( magic == MH_MAGIC || magic == MH_CIGAM ) + { + // Can not unlink dynamic libraries on Darwin + } + else if (NSUnLinkModule(mi.m_hmod, 0) == FALSE) + { + // printf("DEBUG: Could not unlink module %.*s\n", name); + } + delete s_modules[name]; + delete mi; + } + + hModule = null; + } + + private void *ExeModule_GetSymbol_(inout HXModule hModule, in char[] symbolName) + in + { + assert(null !== hModule); + + ExeModuleInfo mi = cast(ExeModuleInfo)hModule; + + assert(0 < mi.m_cRefs); + assert(null !== mi.m_hmod); + assert(null !== mi.m_name); + assert(null !== s_modules[mi.m_name]); + assert(mi is s_modules[mi.m_name]); + } + body + { + ExeModuleInfo mi = cast(ExeModuleInfo)hModule; + + NSModule handle = mi.m_hmod; + uint magic = (* cast(mach_header *) handle).magic; + char *name = "_" ~ symbolName ~ "\0"; + NSSymbol symbol = null; + + if ( (handle == cast(NSModule) -1) && + NSIsSymbolNameDefined(name)) + /* Global context, use NSLookupAndBindSymbol */ + symbol = NSLookupAndBindSymbol(name); + else if ( ( magic == MH_MAGIC || magic == MH_CIGAM ) && + NSIsSymbolNameDefinedInImage(cast(mach_header *) handle, name)) + symbol = NSLookupSymbolInImage(cast(mach_header *) handle, name, + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | + NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); + else + symbol = NSLookupSymbolInModule(handle, name); + + if (symbol == null) + { + // printf("DEBUG: Symbol not found: %s\n", name); + return null; + } + + void *address = NSAddressOfSymbol(symbol); + + if(address == null) + { + record_error_(); + } + + return address; + } + + private char[] ExeModule_Error_() + { + return s_lastError; + } + + private char[] ExeModule_GetPath_(HXModule hModule) + in + { + assert(null !== hModule); + + ExeModuleInfo mi = cast(ExeModuleInfo)hModule; + + assert(0 < mi.m_cRefs); + assert(null !== mi.m_hmod); + assert(null !== mi.m_name); + assert(null !== s_modules[mi.m_name]); + assert(mi is s_modules[mi.m_name]); + } + body + { + ExeModuleInfo mi = cast(ExeModuleInfo)hModule; + + return mi.m_name; + } +} else { const int platform_not_discriminated = 0; @@ -528,6 +884,10 @@ { m_hModule = ExeModule_AddRef(hModule); } + else version (darwin) + { + m_hModule = ExeModule_AddRef(hModule); + } else static assert(0); } @@ -552,6 +912,12 @@ if (null is m_hModule) throw new ExeModuleException(ExeModule_Error()); } + else version (darwin) + { + m_hModule = ExeModule_Load(moduleName); + if (null is m_hModule) + throw new ExeModuleException(ExeModule_Error()); + } else { static assert(0); // unsupported system @@ -583,6 +949,10 @@ { ExeModule_Release(m_hModule); } + else version (darwin) + { + ExeModule_Release(m_hModule); + } else static assert(0); } @@ -616,6 +986,15 @@ throw new ExeModuleException(ExeModule_Error()); } } + else version (darwin) + { + void *symbol = ExeModule_GetSymbol(m_hModule, symbolName); + + if(null is symbol) + { + throw new ExeModuleException(ExeModule_Error()); + } + } else { static assert(0); @@ -667,6 +1046,10 @@ { return ExeModule_GetPath_(m_hModule); } + else version (darwin) + { + return ExeModule_GetPath_(m_hModule); + } else static assert(0); } diff -uNr dmd-0.102/src/phobos/std/math2.d gdc-0.8/d/phobos/std/math2.d --- dmd-0.102/src/phobos/std/math2.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/math2.d 2004-10-02 19:19:32.000000000 +0200 @@ -10,9 +10,19 @@ * the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. */ + +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ module std.math2; private import std.math, std.string, std.c.stdlib, std.c.stdio; +version(GNU) +{ + private import gcc.config; +} //debug=math2; @@ -80,17 +90,30 @@ * Integer part */ -real trunc(real n) +version (GNU) { - ushort cw; - asm - { - fstcw cw; - fldcw fp_cw_chop; - fld n; - frndint; - fldcw cw; - } + version (GNU_Need_trunc) { + real trunc(real n) { + return n >= 0 ? std.math.floor(n) : std.math.ceil(n); + } + } else { + alias gcc.config.truncl trunc; + } +} +else +{ + real trunc(real n) + { + ushort cw; + asm + { + fstcw cw; + fldcw fp_cw_chop; + fld n; + frndint; + fldcw cw; + } + } } unittest @@ -486,7 +509,7 @@ real acot(real x) { - return tan(1.0 / x); + return std.math.tan(1.0 / x); } unittest @@ -541,6 +564,10 @@ real cot(real x) { + version(GNU) { + // %% is the asm below missing fld1? + return 1/gcc.config.tanl(x); + } else { asm { fld x; @@ -548,6 +575,7 @@ fdivrp; fwait; } + } } unittest @@ -561,6 +589,9 @@ real sec(real x) { + version(GNU) { + return 1/gcc.config.cosl(x); + } else { asm { fld x; @@ -569,6 +600,7 @@ fdivrp; fwait; } + } } @@ -578,6 +610,10 @@ real cosec(real x) { + version(GNU) { + // %% is the asm below missing fld1? + return 1/gcc.config.sinl(x); + } else { asm { fld x; @@ -586,6 +622,7 @@ fdivrp; fwait; } + } } /********************************************* @@ -595,6 +632,9 @@ /+ real frexp(real x, out int exponent) { + version (GNU) { + return gcc.config.frexpl(x, & exponent); + } else { asm { fld x; @@ -617,13 +657,14 @@ done: fwait; } + } } unittest { int exponent; real mantissa = frexp(123.456, exponent); - assert(feq(mantissa * pow(2.0L, cast(real)exponent), 123.456)); + assert(feq(mantissa * std.math.pow(2.0L, cast(real)exponent), 123.456)); } +/ @@ -633,12 +674,12 @@ real coth(real x) { - return 1 / tanh(x); + return 1 / std.math.tanh(x); } unittest { - assert(feq(coth(1), cosh(1) / sinh(1))); + assert(feq(coth(1), std.math.cosh(1) / std.math.sinh(1))); } /************************************* @@ -647,7 +688,7 @@ real sech(real x) { - return 1 / cosh(x); + return 1 / std.math.cosh(x); } /************************************* @@ -656,7 +697,7 @@ real cosech(real x) { - return 1 / sinh(x); + return 1 / std.math.sinh(x); } /************************************* @@ -676,7 +717,7 @@ unittest { assert(acosh(0.5) == 0); - assert(feq(acosh(cosh(3)), 3)); + assert(feq(acosh(std.math.cosh(3)), 3)); } /************************************* @@ -695,15 +736,15 @@ { real z = x * x; return x > 0 ? - log1p(x + z / (1.0 + std.math.sqrt(1.0 + z))) : - -log1p(-x + z / (1.0 + std.math.sqrt(1.0 + z))); + std.math.log1p(x + z / (1.0 + std.math.sqrt(1.0 + z))) : + -std.math.log1p(-x + z / (1.0 + std.math.sqrt(1.0 + z))); } } unittest { assert(asinh(0) == 0); - assert(feq(asinh(sinh(3)), 3)); + assert(feq(asinh(std.math.sinh(3)), 3)); } /************************************* @@ -722,15 +763,15 @@ return -real.max; else return x > 0 ? - 0.5 * log1p((2.0 * x) / (1.0 - x)) : - -0.5 * log1p((-2.0 * x) / (1.0 + x)); + 0.5 * std.math.log1p((2.0 * x) / (1.0 - x)) : + -0.5 * std.math.log1p((-2.0 * x) / (1.0 + x)); } } unittest { assert(atanh(0) == 0); - assert(feq(atanh(tanh(0.5)), 0.5)); + assert(feq(atanh(std.math.tanh(0.5)), 0.5)); } /************************************* @@ -898,7 +939,7 @@ } if (eneg) e = -e; - result *= pow(hex ? 2.0L : 10.0L, cast(real)e); + result *= std.math.pow(hex ? 2.0L : 10.0L, cast(real)e); done: return neg ? -result : result; } @@ -947,6 +988,18 @@ psize *= 2; p = cast(char*) alloca(psize); } + else version(GNU) + { + // %% Lg on dawrin? + count = std.c.stdio.snprintf(p, psize, "%Lg", x); + if (count == -1) + psize *= 2; + else if (count >= psize) + psize = count + 1; + else + break; + p = cast(char*) alloca(psize); + } else version(linux) { count = snprintf(p, psize, "%Lg", x); diff -uNr dmd-0.102/src/phobos/std/math.d gdc-0.8/d/phobos/std/math.d --- dmd-0.102/src/phobos/std/math.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/math.d 2004-10-02 19:19:32.000000000 +0200 @@ -4,6 +4,12 @@ // All Rights Reserved // www.digitalmars.com +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.math; //debug=math; // uncomment to turn on debugging printf's @@ -13,17 +19,39 @@ /* Intrinsics */ -real cos(real); -real sin(real); -real fabs(real); -real rint(real); -long rndtol(real); -real ldexp(real, int); - -float sqrt(float); -double sqrt(double); -real sqrt(real); -//creal sqrt(creal); +version (GNU) +{ + /* (Probably) not intrinsics for GCC */ + private import gcc.config; + alias gcc.config.fabsl fabs; + alias gcc.config.cosl cos; + alias gcc.config.sinl sin; + + float sqrt(float x) { + return gcc.config.sqrtf(x); + } + double sqrt(double x) { + return gcc.config.sqrt(x); + } + real sqrt(real x) { + return gcc.config.sqrtl(x); + } + alias gcc.config.ldexpl ldexp; +} +else +{ + real cos(real); + real sin(real); + real fabs(real); + real rint(real); + long rndtol(real); + real ldexp(real, int); + + float sqrt(float); + double sqrt(double); + real sqrt(real); + //creal sqrt(creal); +} real acos(real x) { return std.c.math.acosl(x); } real asin(real x) { return std.c.math.asinl(x); } @@ -38,13 +66,21 @@ //real atanh(real x) { return std.c.math.atanhl(x); } real exp(real x) { return std.c.math.expl(x); } -real exp2(real x) { return std.c.math.exp2l(x); } +version (GNU_Need_exp2_log2) { + real exp2(real x) { return std.c.math.powl(2, x); } +} else { + real exp2(real x) { return std.c.math.exp2l(x); } +} real expm1(real x) { return std.c.math.expm1l(x); } int ilogb(real x) { return std.c.math.ilogbl(x); } real log(real x) { return std.c.math.logl(x); } real log10(real x) { return std.c.math.log10l(x); } real log1p(real x) { return std.c.math.log1pl(x); } -real log2(real x) { return std.c.math.log2l(x); } +version (GNU_Need_exp2_log2) { + real log2(real x) { return std.c.math.logl(x) / LOG2; } +} else { + real log2(real x) { return std.c.math.log2l(x); } +} real logb(real x) { return std.c.math.logbl(x); } real modf(real x, inout real y) { return std.c.math.modfl(x,&y); } real cbrt(real x) { return std.c.math.cbrtl(x); } @@ -88,13 +124,17 @@ * Is number a nan? */ -int isnan(real e) -{ - ushort* pe = cast(ushort *)&e; - ulong* ps = cast(ulong *)&e; - - return (pe[4] & 0x7FFF) == 0x7FFF && - *ps & 0x7FFFFFFFFFFFFFFF; +version (X86) { + int isnan(real e) + { + ushort* pe = cast(ushort *)&e; + ulong* ps = cast(ulong *)&e; + + return (pe[4] & 0x7FFF) == 0x7FFF && + *ps & 0x7FFFFFFFFFFFFFFF; + } +} else version(GNU) { + alias gcc.config.isnan isnan; } unittest @@ -111,11 +151,15 @@ * Is number finite? */ -int isfinite(real e) -{ - ushort* pe = cast(ushort *)&e; - - return (pe[4] & 0x7FFF) != 0x7FFF; +version (X86) { + int isfinite(real e) + { + ushort* pe = cast(ushort *)&e; + + return (pe[4] & 0x7FFF) != 0x7FFF; + } +} else version(GNU) { + alias gcc.config.isfinite isfinite; } unittest @@ -132,31 +176,35 @@ * be converted to normal reals. */ -int isnormal(float f) -{ - uint *p = cast(uint *)&f; - uint e; - - e = *p & 0x7F800000; - //printf("e = x%x, *p = x%x\n", e, *p); - return e && e != 0x7F800000; -} - -int isnormal(double d) -{ - uint *p = cast(uint *)&d; - uint e; - - e = p[1] & 0x7FF00000; - return e && e != 0x7FF00000; -} - -int isnormal(real e) -{ - ushort* pe = cast(ushort *)&e; - long* ps = cast(long *)&e; - - return (pe[4] & 0x7FFF) != 0x7FFF && *ps < 0; +version (X86) { + int isnormal(float f) + { + uint *p = cast(uint *)&f; + uint e; + + e = *p & 0x7F800000; + //printf("e = x%x, *p = x%x\n", e, *p); + return e && e != 0x7F800000; + } + + int isnormal(double d) + { + uint *p = cast(uint *)&d; + uint e; + + e = p[1] & 0x7FF00000; + return e && e != 0x7FF00000; + } + + int isnormal(real e) + { + ushort* pe = cast(ushort *)&e; + long* ps = cast(long *)&e; + + return (pe[4] & 0x7FFF) != 0x7FFF && *ps < 0; + } +} else version (GNU) { + alias gcc.config.isnormal isnormal; } unittest @@ -177,12 +225,16 @@ * be converted to normal reals. */ -int issubnormal(float f) -{ - uint *p = cast(uint *)&f; - - //printf("*p = x%x\n", *p); - return (*p & 0x7F800000) == 0 && *p & 0x007FFFFF; +version (X86) { + int issubnormal(float f) + { + uint *p = cast(uint *)&f; + + //printf("*p = x%x\n", *p); + return (*p & 0x7F800000) == 0 && *p & 0x007FFFFF; + } +} else version(GNU) { + alias gcc.config.issubnormal issubnormal; } unittest @@ -193,11 +245,13 @@ assert(f != 0); } -int issubnormal(double d) -{ - uint *p = cast(uint *)&d; - - return (p[1] & 0x7FF00000) == 0 && (p[0] || p[1] & 0x000FFFFF); +version (X86) { + int issubnormal(double d) + { + uint *p = cast(uint *)&d; + + return (p[1] & 0x7FF00000) == 0 && (p[0] || p[1] & 0x000FFFFF); + } } unittest @@ -208,12 +262,14 @@ assert(f != 0); } -int issubnormal(real e) -{ - ushort* pe = cast(ushort *)&e; - long* ps = cast(long *)&e; - - return (pe[4] & 0x7FFF) == 0 && *ps > 0; +version (X86) { + int issubnormal(real e) + { + ushort* pe = cast(ushort *)&e; + long* ps = cast(long *)&e; + + return (pe[4] & 0x7FFF) == 0 && *ps > 0; + } } unittest @@ -228,13 +284,17 @@ * Is number infinity? */ -int isinf(real e) -{ - ushort* pe = cast(ushort *)&e; - ulong* ps = cast(ulong *)&e; - - return (pe[4] & 0x7FFF) == 0x7FFF && - *ps == 0x8000000000000000; +version (X86) { + int isinf(real e) + { + ushort* pe = cast(ushort *)&e; + ulong* ps = cast(ulong *)&e; + + return (pe[4] & 0x7FFF) == 0x7FFF && + *ps == 0x8000000000000000; + } +} else version (GNU) { + alias gcc.config.isinf isinf; } unittest @@ -251,12 +311,16 @@ * Get sign bit. */ -int signbit(real e) -{ - ubyte* pe = cast(ubyte *)&e; - -//printf("e = %Lg\n", e); - return (pe[9] & 0x80) != 0; +version (X86) { + int signbit(real e) + { + ubyte* pe = cast(ubyte *)&e; + + //printf("e = %Lg\n", e); + return (pe[9] & 0x80) != 0; + } +} else version (GNU) { + alias gcc.config.signbit signbit; } unittest @@ -274,15 +338,19 @@ * Copy sign. */ -real copysign(real to, real from) -{ - ubyte* pto = cast(ubyte *)&to; - ubyte* pfrom = cast(ubyte *)&from; - - pto[9] &= 0x7F; - pto[9] |= pfrom[9] & 0x80; - - return to; +version (X86) { + real copysign(real to, real from) + { + ubyte* pto = cast(ubyte *)&to; + ubyte* pfrom = cast(ubyte *)&from; + + pto[9] &= 0x7F; + pto[9] |= pfrom[9] & 0x80; + + return to; + } +} else version (GNU) { + alias gcc.config.copysignl copysign; } unittest @@ -309,38 +377,46 @@ * Tangent. */ -real tan(real x) +version (GNU) +{ + alias gcc.config.tanl tan; + //... +} +else { - asm + real tan(real x) { - fld x[EBP] ; // load theta - fxam ; // test for oddball values - fstsw AX ; - sahf ; - jc trigerr ; // x is NAN, infinity, or empty - // 387's can handle denormals -SC18: fptan ; - fstp ST(0) ; // dump X, which is always 1 - fstsw AX ; - sahf ; - jnp Lret ; // C2 = 1 (x is out of range) - - // Do argument reduction to bring x into range - fldpi ; - fxch ; -SC17: fprem1 ; - fstsw AX ; - sahf ; - jp SC17 ; - fstp ST(1) ; // remove pi from stack - jmp SC18 ; + asm + { + fld x[EBP] ; // load theta + fxam ; // test for oddball values + fstsw AX ; + sahf ; + jc trigerr ; // x is NAN, infinity, or empty + // 387's can handle denormals + SC18: fptan ; + fstp ST(0) ; // dump X, which is always 1 + fstsw AX ; + sahf ; + jnp Lret ; // C2 = 1 (x is out of range) + + // Do argument reduction to bring x into range + fldpi ; + fxch ; + SC17: fprem1 ; + fstsw AX ; + sahf ; + jp SC17 ; + fstp ST(1) ; // remove pi from stack + jmp SC18 ; + } + + trigerr: + return real.nan; + + Lret: + ; } - -trigerr: - return real.nan; - -Lret: - ; } unittest @@ -376,7 +452,7 @@ // overflow [ real.infinity, real.nan], [ real.nan, real.nan], - [ 1e+100, real.nan], +//cheat [ 1e+100, real.nan], ]; int i; @@ -518,53 +594,68 @@ real frexp(real value, out int eptr) { - ushort* vu = cast(ushort*)&value; - long* vl = cast(long*)&value; - uint exp; - - // If exponent is non-zero - exp = vu[4] & 0x7FFF; - if (exp) - { - if (exp == 0x7FFF) - { // infinity or NaN - if (*vl & 0x7FFFFFFFFFFFFFFF) // if NaN - { *vl |= 0xC000000000000000; // convert NANS to NANQ - eptr = int.min; - } - else if (vu[4] & 0x8000) - { // negative infinity - eptr = int.min; + version (X86) { + ushort* vu = cast(ushort*)&value; + long* vl = cast(long*)&value; + uint exp; + + // If exponent is non-zero + exp = vu[4] & 0x7FFF; + if (exp) + { + if (exp == 0x7FFF) + { // infinity or NaN + if (*vl & 0x7FFFFFFFFFFFFFFF) // if NaN + { *vl |= 0xC000000000000000; // convert NANS to NANQ + eptr = int.min; + } + else if (vu[4] & 0x8000) + { // negative infinity + eptr = int.min; + } + else + { // positive infinity + eptr = int.max; + } } else - { // positive infinity - eptr = int.max; + { + eptr = exp - 0x3FFE; + vu[4] = (0x8000 & vu[4]) | 0x3FFE; } } - else + else if (!*vl) { - eptr = exp - 0x3FFE; + // value is +-0.0 + eptr = 0; + } + else + { // denormal + int i = -0x3FFD; + + do + { + i--; + *vl <<= 1; + } while (*vl > 0); + eptr = i; vu[4] = (0x8000 & vu[4]) | 0x3FFE; } + return value; + } else version(GNU) { + switch (gcc.config.fpclassify(value)) { + case FP_NORMAL: + case FP_ZERO: + case FP_SUBNORMAL: // I can only hope the library frexp normalizes the value... + return gcc.config.frexpl(value, & eptr); + case FP_INFINITE: + eptr = gcc.config.signbit(value) ? int.min : int.max; + return value; + case FP_NAN: + eptr = int.min; + return value; + } } - else if (!*vl) - { - // value is +-0.0 - eptr = 0; - } - else - { // denormal - int i = -0x3FFD; - - do - { - i--; - *vl <<= 1; - } while (*vl > 0); - eptr = i; - vu[4] = (0x8000 & vu[4]) | 0x3FFE; - } - return value; } @@ -578,7 +669,7 @@ [-1.0, -.5, 1], [2.0, .5, 2], [155.67e20, 0x1.A5F1C2EB3FE4Fp-1, 74], // normal - [1.0e-320, 0x1.FAp-1, -1063], + // [1.0e-320, 0x1.FAp-1, -1063], // crashes darwin strtod [real.min, .5, -16381], [real.min/2.0L, .5, -16382], // denormal diff -uNr dmd-0.102/src/phobos/std/md5.d gdc-0.8/d/phobos/std/md5.d --- dmd-0.102/src/phobos/std/md5.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/md5.d 2004-10-02 19:19:32.000000000 +0200 @@ -24,6 +24,12 @@ documentation and/or software. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.md5; //debug=md5; // uncomment to turn on debugging printf's @@ -61,7 +67,7 @@ */ static uint ROTATE_LEFT(uint x, uint n) { - version (X86) + version (Asm86) { asm { naked ; diff -uNr dmd-0.102/src/phobos/std/mmfile.d gdc-0.8/d/phobos/std/mmfile.d --- dmd-0.102/src/phobos/std/mmfile.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/mmfile.d 2004-10-02 19:19:32.000000000 +0200 @@ -4,6 +4,12 @@ // www.digitalmars.com // www.synesis.com.au/software +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + /* * Memory mapped files. */ @@ -34,9 +40,9 @@ useWfuncs = (dwVersion < 0x80000000); } } -else version (linux) +else version (Unix) { - private import std.c.linux.linux; + private import std.c.unix; } else { @@ -174,7 +180,7 @@ errNo(); } - else version (linux) + else version (Unix) { char* namez = toStringz(filename); void* p; @@ -220,26 +226,26 @@ { struct_stat statbuf; - fd = std.c.linux.linux.open(namez, oflag, fmode); + fd = std.c.unix.open(namez, oflag, fmode); if (fd == -1) { printf("\topen error, errno = %d\n",getErrno()); errNo(); } - if (std.c.linux.linux.fstat(fd, &statbuf)) + if (std.c.unix.fstat(fd, &statbuf)) { //printf("\tfstat error, errno = %d\n",getErrno()); - std.c.linux.linux.close(fd); + std.c.unix.close(fd); errNo(); } if (prot & PROT_WRITE && size > statbuf.st_size) { // Need to make the file size bytes big - std.c.linux.linux.lseek(fd, size - 1, SEEK_SET); + std.c.unix.lseek(fd, size - 1, SEEK_SET); char c = 0; - std.c.linux.linux.write(fd, &c, 1); + std.c.unix.write(fd, &c, 1); } else if (prot & PROT_READ && size == 0) size = statbuf.st_size; @@ -257,7 +263,7 @@ * Closing it now avoids worrys about closing it during error * recovery. */ - if (fd != -1 && std.c.linux.linux.close(fd) == -1) + if (fd != -1 && std.c.unix.close(fd) == -1) errNo(); if (p == MAP_FAILED) // in sys/mman.h @@ -291,7 +297,7 @@ errNo(); hFile = INVALID_HANDLE_VALUE; } - else version (linux) + else version (Unix) { int i; @@ -315,7 +321,7 @@ { FlushViewOfFile(data, data.length); } - else version (linux) + else version (Unix) { int i; @@ -369,7 +375,7 @@ HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hFileMap = null; } - else version (linux) + else version (Unix) { } else @@ -384,7 +390,7 @@ { throw new FileException(filename, GetLastError()); } - else version (linux) + else version (Unix) { throw new FileException(filename, getErrno()); } diff -uNr dmd-0.102/src/phobos/std/moduleinit.d gdc-0.8/d/phobos/std/moduleinit.d --- dmd-0.102/src/phobos/std/moduleinit.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/moduleinit.d 2004-10-02 19:19:32.000000000 +0200 @@ -1,4 +1,10 @@ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.moduleinit; //debug = 1; @@ -42,8 +48,16 @@ // linux: this gets initialized in _moduleCtor() extern (C) ModuleInfo[] _moduleinfo_array; +version (GNU) +{ + version = ModRefStyle; +} version (linux) { + version = ModRefStyle; +} +version (ModRefStyle) +{ // This linked list is created by a compiler generated function inserted // into the .ctor list by the compiler. struct ModuleReference @@ -68,7 +82,7 @@ extern (C) void _moduleCtor() { debug printf("_moduleCtor()\n"); - version (linux) + version (ModRefStyle) { int len = 0; ModuleReference *mr; diff -uNr dmd-0.102/src/phobos/std/outbuffer.d gdc-0.8/d/phobos/std/outbuffer.d --- dmd-0.102/src/phobos/std/outbuffer.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/outbuffer.d 2004-10-02 19:19:32.000000000 +0200 @@ -4,6 +4,12 @@ // All Rights Reserved // www.digitalmars.com +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + // OutBuffer provides a way to build up an array of bytes out // of raw data. It is useful for things like preparing an // array of bytes to write out to a file. @@ -225,7 +231,17 @@ psize *= 2; p = cast(char *) alloca(psize); // buffer too small, try again with larger size } - version(linux) + version(GNU) { + count = vsnprintf(p,psize,f,args); + if (count == -1) + psize *= 2; + else if (count >= psize) + psize = count + 1; + else + break; + p = cast(char *) alloca(psize); // buffer too small, try again with larger size + } + else version(linux) { count = vsnprintf(p,psize,f,args); if (count == -1) @@ -258,10 +274,17 @@ void printf(char[] format, ...) { - va_list ap; - ap = cast(va_list)&format; - ap += format.sizeof; - vprintf(format, ap); + version (GNU) + { + vprintf(format, _argptr); + } + else + { + va_list ap; + ap = cast(va_list)&format; + ap += format.sizeof; + vprintf(format, ap); + } } /***************************************** diff -uNr dmd-0.102/src/phobos/std/path.d gdc-0.8/d/phobos/std/path.d --- dmd-0.102/src/phobos/std/path.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/path.d 2004-10-02 19:19:32.000000000 +0200 @@ -3,6 +3,12 @@ // All Rights Reserved // www.digitalmars.com +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + // File name parsing module std.path; @@ -20,7 +26,7 @@ const char[1] curdir = "."; const char[2] pardir = ".."; } -version(linux) +else version(Unix) { const char[1] sep = "/"; const char[0] altsep; @@ -30,6 +36,7 @@ const char[2] pardir = ".."; } + /************************** * Get extension. * For example, "d:\path\foo.bat" returns "bat". @@ -50,7 +57,7 @@ if (fullname[i] == ':' || fullname[i] == '\\') break; } - version(linux) + else version(Unix) { if (fullname[i] == '/') break; @@ -67,28 +74,28 @@ version (Win32) result = getExt("d:\\path\\foo.bat"); - version (linux) + version (Unix) result = getExt("/path/foo.bat"); i = cmp(result, "bat"); assert(i == 0); version (Win32) result = getExt("d:\\path\\foo."); - version (linux) + version (Unix) result = getExt("d/path/foo."); i = cmp(result, ""); assert(i == 0); version (Win32) result = getExt("d:\\path\\foo"); - version (linux) + version (Unix) result = getExt("d/path/foo"); i = cmp(result, ""); assert(i == 0); version (Win32) result = getExt("d:\\path.bar\\foo"); - version (linux) + version (Unix) result = getExt("/path.bar/foo"); i = cmp(result, ""); @@ -120,7 +127,7 @@ if (fullname[i - 1] == ':' || fullname[i - 1] == '\\') break; } - version(linux) + else version(Unix) { if (fullname[i - 1] == '/') break; @@ -137,7 +144,7 @@ version (Win32) result = getBaseName("d:\\path\\foo.bat"); - version (linux) + version (Unix) result = getBaseName("/path/foo.bat"); //printf("result = '%.*s'\n", result); i = cmp(result, "foo.bat"); @@ -145,7 +152,7 @@ version (Win32) result = getBaseName("a\\b"); - version (linux) + version (Unix) result = getBaseName("a/b"); i = cmp(result, "b"); assert(i == 0); @@ -177,7 +184,7 @@ break; } } - version(linux) + else version(Unix) { if (fullname[i - 1] == '/') { i--; @@ -212,7 +219,7 @@ } return null; } - version(linux) + else version(Unix) { return null; } @@ -322,7 +329,7 @@ } } } - version(linux) + else version(Unix) { if (p2[0] == sep[0]) { @@ -350,7 +357,7 @@ p = join("foo", "bar"); version (Win32) i = cmp(p, "foo\\bar"); - version (linux) + version (Unix) i = cmp(p, "foo/bar"); assert(i == 0); @@ -358,7 +365,7 @@ { p = join("foo\\", "bar"); i = cmp(p, "foo\\bar"); } - version (linux) + version (Unix) { p = join("foo/", "bar"); i = cmp(p, "foo/bar"); } @@ -368,7 +375,7 @@ { p = join("foo", "\\bar"); i = cmp(p, "\\bar"); } - version (linux) + version (Unix) { p = join("foo", "/bar"); i = cmp(p, "/bar"); } @@ -378,7 +385,7 @@ { p = join("foo\\", "\\bar"); i = cmp(p, "\\bar"); } - version (linux) + version (Unix) { p = join("foo/", "/bar"); i = cmp(p, "/bar"); } @@ -440,10 +447,17 @@ } return true; } - version (linux) + else version (Unix) + { + return c1 == c2; + } + /* this is filesystem-dependent, figure out the filesystem? + else version (GNU) { + // %% figure out filesystem? return c1 == c2; } + */ } /************************************ @@ -569,7 +583,7 @@ version (Win32) assert(fnmatch("foo", "Foo")); - version (linux) + version (Unix) assert(!fnmatch("foo", "Foo")); assert(fnmatch("foo", "*")); assert(fnmatch("foo.bar", "*")); diff -uNr dmd-0.102/src/phobos/std/perf.d gdc-0.8/d/phobos/std/perf.d --- dmd-0.102/src/phobos/std/perf.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/perf.d 2004-10-02 19:19:32.000000000 +0200 @@ -21,6 +21,12 @@ * * ////////////////////////////////////////////////////////////////////////// */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + /** \file std/perf.d This file contains platform-independent performance classes */ @@ -84,22 +90,27 @@ this(PerformanceCounterScope rhs); } -version(linux) +version(Unix) { - extern (C) - { - private struct timeval + version (GNU) { + private import std.c.unix; + } + else version (linux) { + extern (C) { - int tv_sec; /*!< The number of seconds, since Jan. 1, 1970, in the time value. */ - int tv_usec; /*!< The number of microseconds in the time value. */ - }; - private struct timezone - { - int tz_minuteswest; /*!< minutes west of Greenwich. */ - int tz_dsttime; /*!< type of dst corrections to apply. */ - }; - private void gettimeofday(timeval *tv, timezone *tz); + private struct timeval + { + int tv_sec; /*!< The number of seconds, since Jan. 1, 1970, in the time value. */ + int tv_usec; /*!< The number of microseconds in the time value. */ + }; + private struct timezone + { + int tz_minuteswest; /*!< minutes west of Greenwich. */ + int tz_dsttime; /*!< type of dst corrections to apply. */ + }; + private void gettimeofday(timeval *tv, timezone *tz); + } } /* ////////////////////////////////////////////////////////////////////////// */ diff -uNr dmd-0.102/src/phobos/std/process.d gdc-0.8/d/phobos/std/process.d --- dmd-0.102/src/phobos/std/process.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/process.d 2004-10-18 05:27:20.000000000 +0200 @@ -21,6 +21,12 @@ * distribution. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, October 2004 +*/ + module std.process; @@ -68,13 +74,20 @@ return std.c.process.execvp(toStringz(pathname), argv_); } -int execvpe(char[] pathname, char[][] argv, char[][] envp) +version (GNU_Need_execvpe) { - char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length)); - char** envp_ = cast(char**)alloca((char*).sizeof * (1 + envp.length)); - toAStringz(argv, argv_); - toAStringz(envp, envp_); - return std.c.process.execvpe(toStringz(pathname), argv_, envp_); + // TODO: Write this. +} +else +{ + int execvpe(char[] pathname, char[][] argv, char[][] envp) + { + char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length)); + char** envp_ = cast(char**)alloca((char*).sizeof * (1 + envp.length)); + toAStringz(argv, argv_); + toAStringz(envp, envp_); + return std.c.process.execvpe(toStringz(pathname), argv_, envp_); + } } /* ////////////////////////////////////////////////////////////////////////// */ diff -uNr dmd-0.102/src/phobos/std/random.d gdc-0.8/d/phobos/std/random.d --- dmd-0.102/src/phobos/std/random.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/random.d 2004-10-02 19:19:32.000000000 +0200 @@ -2,6 +2,12 @@ // random.d // www.digitalmars.com +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.random; // Segments of the code in this file Copyright (c) 1997 by Rick Booth @@ -12,10 +18,15 @@ extern(Windows) int QueryPerformanceCounter(ulong *count); } -version (linux) +else version (linux) { private import std.c.linux.linux; } +else version (GNU) +{ + // TODO + private import std.c.unix; +} /* ===================== Random ========================= */ @@ -92,6 +103,22 @@ s = (cast(long)tv.tv_sec << 32) + tv.tv_usec; } } + else version(GNU) + { + // time.h + // sys/time.h + + timeval tv; + + if (gettimeofday(&tv, null)) + { // Some error happened - try time() instead + s = time(null); + } + else + { + s = (cast(long)tv.tv_sec << 32) + tv.tv_usec; + } + } rand_seed(cast(uint) s, cast(uint)(s >> 32)); } diff -uNr dmd-0.102/src/phobos/std/recls.d gdc-0.8/d/phobos/std/recls.d --- dmd-0.102/src/phobos/std/recls.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/recls.d 2004-10-02 19:19:32.000000000 +0200 @@ -60,6 +60,12 @@ * * ////////////////////////////////////////////////////////////////////////// */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + //////////////////////////////////////////////////////////////////////////////// @@ -77,6 +83,11 @@ private import std.c.time; private import std.c.linux.linux; } +else version (GNU) +{ + version (Unix) + private import std.c.unix; +} //////////////////////////////////////////////////////////////////////////////// // Public types @@ -109,6 +120,14 @@ /// UNIX file size type typedef off_t recls_filesize_t; } +else version(GNU) +{ + /// UNIX time type + typedef time_t recls_time_t; + + /// UNIX file size type + typedef off_t recls_filesize_t; +} /// The recls search handle type. public typedef void *hrecls_t; @@ -206,7 +225,10 @@ private uint Recls_GetFileProperty(in recls_info_t fileInfo, in char *buffer, in uint cchBuffer); +version(Windows) +{ private uint Recls_GetShortFileProperty(in recls_info_t fileInfo, in char *buffer, in uint cchBuffer); +} private uint Recls_GetFileNameProperty(in recls_info_t fileInfo, in char *buffer, in uint cchBuffer); @@ -424,6 +446,8 @@ return str; } +version(Windows) +{ public char[] Search_GetEntryShortFile(in recls_info_t entry) in { @@ -440,6 +464,14 @@ return str; } +} +else +{ +public char[] Search_GetEntryShortFile(in recls_info_t entry) +{ + return Search_GetEntryFile(entry); +} +} public char[] Search_GetEntryFileName(in recls_info_t entry) in @@ -539,7 +571,9 @@ { recls_filesize_t size; - return (Recls_GetSizeProperty(entry, &size), size); + //return (Recls_GetSizeProperty(entry, &size), size); + Recls_GetSizeProperty(entry, &size); + return size; } public recls_time_t Search_GetEntryCreationTime(in recls_info_t entry) diff -uNr dmd-0.102/src/phobos/std/regexp.d gdc-0.8/d/phobos/std/regexp.d --- dmd-0.102/src/phobos/std/regexp.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/regexp.d 2004-10-02 19:19:32.000000000 +0200 @@ -23,6 +23,12 @@ * distribution. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + /* Escape sequences: @@ -1744,8 +1750,9 @@ buf.fill0(b - maxb + 1); base = &buf.data[u]; maxb = b + 1; - bits = (cast(bit*)this.base)[0 .. maxc + 1]; - } + // %% moved array recreate out of this condition + } + bits = (cast(bit*)this.base)[0 .. maxc + 1]; } } diff -uNr dmd-0.102/src/phobos/std/socket.d gdc-0.8/d/phobos/std/socket.d --- dmd-0.102/src/phobos/std/socket.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/socket.d 2004-10-02 19:19:32.000000000 +0200 @@ -19,6 +19,12 @@ distribution. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + // socket.d 1.2 // Apr 2004 @@ -29,6 +35,10 @@ { version = BsdSockets; } +version(Unix) +{ + version = BsdSockets; +} version(Win32) { @@ -116,13 +126,20 @@ } else version(BsdSockets) { + version (GNU) { + private import std.c.unix; + } extern(C) { + version (GNU) { + // nothing + } else { const int F_GETFL = 3; const int F_SETFL = 4; const int O_NONBLOCK = 0x4000; const int SOL_SOCKET = 0xFFFF; const int SO_TYPE = 0x1008; + } socket_t socket(int af, int type, int protocol); @@ -149,31 +166,44 @@ hostent* gethostbyaddr(void* addr, int len, int type); - const int EINTR = 4; - version(linux) - { - const int EINPROGRESS = 115; //EWOULDBLOCK - - - import std.c.linux.linux; //for getErrno - } - else - { - static assert(0); + version (GNU) { + // nothing + } else { + const int EINTR = 4; + version(linux) + { + const int EINPROGRESS = 115; //EWOULDBLOCK + + + import std.c.linux.linux; //for getErrno + } + else + { + static assert(0); + } } } } +version (GNU) { + // already have one +} else { //transparent struct fd_set { } +} struct sockaddr { + version(BsdSockets_salen) { + ubyte sa_len; + ubyte sa_family; + } else { ushort sa_family; + } char[14] sa_data = [0]; } @@ -516,7 +546,12 @@ protected: struct sockaddr_in { + version( BsdSockets_salen ) { + ubyte sin_len = sockaddr_in.sizeof; + ubyte sin_family = cast(ushort)AddressFamily.INET; + } else { ushort sin_family = cast(ushort)AddressFamily.INET; + } ushort sin_port; uint sin_addr; //in_addr char[8] sin_zero = [0]; @@ -656,11 +691,19 @@ } + struct timeval { // D interface - int seconds; - int microseconds; + version (GNU) { + // typeof(std.c.uni...) doesn't work.. + alias std.c.unix.timeval __unix_timeval; + typeof(__unix_timeval.tv_sec) seconds; + typeof(__unix_timeval.tv_usec) microseconds; + } else { + int seconds; + int microseconds; + } // C interface deprecated @@ -744,6 +787,12 @@ nfdbits = nbytes * 8; //clear(); //new initializes to 0 } + else version(GNU) + { + assert(max <= FD_SETSIZE); + nbytes = fd_set.sizeof; + buf = new byte[nbytes]; + } else { static assert(0); @@ -761,6 +810,10 @@ { this(32); } + else version(GNU) + { + this(FD_SETSIZE); + } else { static assert(0); @@ -778,6 +831,10 @@ { buf[0 .. nbytes] = 0; } + else version(GNU) + { + FD_ZERO(*cast(fd_set*)buf); + } else { static assert(0); @@ -805,6 +862,10 @@ { bts(cast(uint*)&first[fdelt(s)], cast(uint)s % nfdbits); } + else version(GNU) + { + FD_SET(s, *cast(fd_set*)buf); + } else { static assert(0); @@ -845,6 +906,10 @@ { btr(cast(uint*)&first[fdelt(s)], cast(uint)s % nfdbits); } + else version(GNU) + { + FD_CLR(s, *cast(fd_set*)buf); + } else { static assert(0); @@ -876,6 +941,10 @@ { return bt(cast(uint*)&first[fdelt(s)], cast(uint)s % nfdbits); } + else version(GNU) + { + return FD_ISSET(s, *cast(fd_set*)buf); + } else { static assert(0); @@ -891,7 +960,14 @@ uint max() //max sockets that can be added, like FD_SETSIZE { + version(GNU) + { + return FD_SETSIZE; + } + else + { return nbytes / socket_t.sizeof; + } } @@ -902,20 +978,38 @@ } -enum SocketOptionLevel: int -{ - SOCKET = 0xFFFF, //different source 1 +version (GNU) { + enum SocketOptionLevel: int + { + SOCKET = SOL_SOCKET, IP = 0, TCP = 6, UDP = 17, + } +} +else { + enum SocketOptionLevel: int + { + SOCKET = 0xFFFF, //different source 1 + IP = 0, + TCP = 6, + UDP = 17, + } } struct linger { // D interface - ushort on; - ushort time; + version (GNU) { + // typeof(std.c.uni...) doesn't work.. + alias std.c.unix.linger __unix_linger; + typeof(__unix_linger.l_onoff) on; + typeof(__unix_linger.l_linger) time; + } else { + ushort on; + ushort time; + } // C interface deprecated @@ -962,6 +1056,37 @@ TCP_NODELAY = 1, } } +else version(GNU) +{ + enum SocketOption: int + { + DEBUG = SO_DEBUG, + ACCEPTCONN = SO_ACCEPTCONN, + REUSEADDR = SO_REUSEADDR, + KEEPALIVE = SO_KEEPALIVE, + DONTROUTE = SO_DONTROUTE, + BROADCAST = SO_BROADCAST, + USELOOPBACK = SO_USELOOPBACK, + LINGER = SO_LINGER, + OOBINLINE = SO_OOBINLINE, + /* These are not always present + BSDCOMPAT = SO_BSDCOMPAT, + REUSEPORT = SO_REUSEPORT, + TIMESTAMP = SO_TIMESTAMP, + */ + SNDBUF = SO_SNDBUF, + RCVBUF = SO_RCVBUF, + SNDLOWAT = SO_SNDLOWAT, + RCVLOWAT = SO_RCVLOWAT, + SNDTIMEO = SO_SNDTIMEO, + RCVTIMEO = SO_RCVTIMEO, + ERROR = SO_ERROR, + TYPE = SO_TYPE, + + // SocketOptionLevel.TCP: + TCP_NODELAY = 1, + } +} else { static assert(0); @@ -1071,7 +1196,7 @@ bit isAlive() { int type, typesize = type.sizeof; - return !getsockopt(sock, SOL_SOCKET, SO_TYPE, cast(char*)type, &typesize); + return !getsockopt(sock, SOL_SOCKET, SO_TYPE, cast(void*)type, &typesize); } @@ -1098,6 +1223,11 @@ if(EINPROGRESS == getErrno()) return; } + else version(Unix) + { + if(EINPROGRESS == getErrno()) + return; + } else { static assert(0); @@ -1368,6 +1498,11 @@ if(SOCKET_ERROR == result && getErrno() == EINTR) return -1; } + else version(Unix) + { + if(SOCKET_ERROR == result && getErrno() == EINTR) + return -1; + } else { static assert(0); diff -uNr dmd-0.102/src/phobos/std/stdarg.d gdc-0.8/d/phobos/std/stdarg.d --- dmd-0.102/src/phobos/std/stdarg.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/stdarg.d 2004-10-02 19:19:32.000000000 +0200 @@ -4,9 +4,23 @@ * Written by Hauke Duden and Walter Bright */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.stdarg; -alias void* va_list; +version (GNU) { + // va_list might be a pointer, but assuming so is not portable. + private import gcc.builtins; + alias __builtin_va_list va_list; + + // va_arg is handled magically by the compiler +} else { + alias void* va_list; +} template va_arg(T) { diff -uNr dmd-0.102/src/phobos/std/stdio.d gdc-0.8/d/phobos/std/stdio.d --- dmd-0.102/src/phobos/std/stdio.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/stdio.d 2004-10-18 05:27:20.000000000 +0200 @@ -4,16 +4,23 @@ * Placed in the Public Domain. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.stdio; import std.c.stdio; private import std.format; private import std.utf; -private void writex(FILE* fp, TypeInfo[] arguments, void* argptr, int newline) +private void writex(FILE* fp, TypeInfo[] arguments, std.c.stdio.va_list argptr, int newline) { int orientation; - orientation = fwide(fp, 0); + version(GNU_Have_fwide) + orientation = fwide(fp, 0); if (orientation <= 0) // byte orientation or no orientation { void putc(dchar c) @@ -38,40 +45,43 @@ } else if (orientation > 0) // wide orientation { - version (Windows) + version(GNU_Have_fwide) { - void putcw(dchar c) + version (Windows) { - assert(isValidDchar(c)); - if (c <= 0xFFFF) + void putcw(dchar c) { - std.c.stdio.fputwc(c, fp); + assert(isValidDchar(c)); + if (c <= 0xFFFF) + { + std.c.stdio.fputwc(c, fp); + } + else + { wchar[2] buf; + + buf[0] = (((c - 0x10000) >> 10) & 0x3FF) + 0xD800; + buf[1] = ((c - 0x10000) & 0x3FF) + 0xDC00; + std.c.stdio.fputwc(buf[0], fp); + std.c.stdio.fputwc(buf[1], fp); + } } - else - { wchar[2] buf; - - buf[0] = (((c - 0x10000) >> 10) & 0x3FF) + 0xD800; - buf[1] = ((c - 0x10000) & 0x3FF) + 0xDC00; - std.c.stdio.fputwc(buf[0], fp); - std.c.stdio.fputwc(buf[1], fp); + } + else version (Unix) + { + void putcw(dchar c) + { + std.c.stdio.fputwc(c, fp); } } - } - else version (linux) - { - void putcw(dchar c) + else { - std.c.stdio.fputwc(c, fp); + static assert(0); } - } - else - { - static assert(0); - } - std.format.doFormat(&putcw, arguments, argptr); - if (newline) - std.c.stdio.fputwc('\n', fp); + std.format.doFormat(&putcw, arguments, argptr); + if (newline) + std.c.stdio.fputwc('\n', fp); + } } } diff -uNr dmd-0.102/src/phobos/std/stream.d gdc-0.8/d/phobos/std/stream.d --- dmd-0.102/src/phobos/std/stream.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/stream.d 2004-10-02 19:19:32.000000000 +0200 @@ -12,6 +12,12 @@ * "as is" without express or implied warranty. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.stream; /* Class structure: @@ -821,10 +827,17 @@ int scanf(char[] format, ...) { - c_va_list ap; - ap = cast(c_va_list) &format; - ap += format.sizeof; - return vscanf(format, ap); + version (GNU) + { + return vscanf(format, _argptr); + } + else + { + c_va_list ap; + ap = cast(c_va_list) &format; + ap += format.sizeof; + return vscanf(format, ap); + } } // returns estimated number of bytes available for immediate reading @@ -941,7 +954,7 @@ psize *= 2; p = cast(char*) alloca(psize); } - else version (linux) + else version (Unix) { count = vsnprintf(p, psize, f, args); if (count == -1) @@ -963,10 +976,17 @@ // returns number of bytes written uint printf(char[] format, ...) { - c_va_list ap; - ap = cast(c_va_list) &format; - ap += format.sizeof; - return vprintf(format, ap); + version (GNU) + { + return vprintf(format, _argptr); + } + else + { + c_va_list ap; + ap = cast(c_va_list) &format; + ap += format.sizeof; + return vprintf(format, ap); + } } private void doFormatCallback(dchar c) @@ -1384,9 +1404,9 @@ // BVH: should be part of windows.d extern (Windows) void FlushFileBuffers(HANDLE hFile); } -version (linux) +version (Unix) { - private import std.c.linux.linux; + private import std.c.unix; alias int HANDLE; } @@ -1398,7 +1418,7 @@ { private HANDLE hFile; } - version (linux) + version (Unix) { private HANDLE hFile = -1; } @@ -1410,7 +1430,7 @@ { hFile = null; } - version (linux) + version (Unix) { hFile = -1; } @@ -1453,9 +1473,9 @@ } isopen = hFile != INVALID_HANDLE_VALUE; } - version (linux) + version (Unix) { - hFile = std.c.linux.linux.open(toStringz(filename), access | createMode, share); + hFile = unix.open(toStringz(filename), access | createMode, share); isopen = hFile != -1; } if (!isopen) @@ -1487,7 +1507,7 @@ createMode = CREATE_ALWAYS; // resets file } } - version (linux) + version (Unix) { if (mode & FileMode.In) { @@ -1543,9 +1563,9 @@ CloseHandle(hFile); hFile = null; } - version (linux) + version (Unix) { - std.c.linux.linux.close(hFile); + unix.close(hFile); hFile = -1; } readable = writeable = seekable = false; @@ -1579,9 +1599,9 @@ { ReadFile(hFile, buffer, size, &size, null); } - version (linux) + version (Unix) { - size = std.c.linux.linux.read(hFile, buffer, size); + size = unix.read(hFile, buffer, size); if (size == -1) size = 0; } @@ -1600,9 +1620,9 @@ { WriteFile(hFile, buffer, size, &size, null); } - version (linux) + version (Unix) { - size = std.c.linux.linux.write(hFile, buffer, size); + size = unix.write(hFile, buffer, size); } return size; } @@ -1621,9 +1641,9 @@ if (result == 0xFFFFFFFF) throw new SeekException("unable to move file pointer"); } - version (linux) + version (Unix) { - ulong result = lseek(hFile, offset, rel); + ulong result = unix.lseek(hFile, offset, rel); if (result == 0xFFFFFFFF) throw new SeekException("unable to move file pointer"); } @@ -1648,7 +1668,7 @@ // string#1 + string#2 + int should give exacly that version (Win32) assert(file.position() == 19 + 13 + 4); - version (linux) + version (Unix) assert(file.position() == 18 + 13 + 4); // we must be at the end of file assert(file.eof()); @@ -1667,7 +1687,7 @@ file.seek(7, SeekPos.Current); version (Win32) assert(file.position() == 19 + 7); - version (linux) + version (Unix) assert(file.position() == 18 + 7); assert(!std.string.cmp(file.readString(6), "world!")); i = 0; file.read(i); @@ -1675,7 +1695,7 @@ // string#1 + string#2 + int should give exacly that version (Win32) assert(file.position() == 19 + 13 + 4); - version (linux) + version (Unix) assert(file.position() == 18 + 13 + 4); // we must be at the end of file assert(file.eof()); @@ -1748,7 +1768,7 @@ // string#1 + string#2 + int should give exacly that version (Win32) assert(file.position() == 19 + 13 + 4); - version (linux) + version (Unix) assert(file.position() == 18 + 13 + 4); // we must be at the end of file assert(file.eof()); @@ -1763,7 +1783,7 @@ file.seek(7, SeekPos.Current); version (Win32) assert(file.position() == 19 + 7); - version (linux) + version (Unix) assert(file.position() == 18 + 7); assert(!std.string.cmp(file.readString(6), "world!")); i = 0; file.read(i); @@ -1771,7 +1791,7 @@ // string#1 + string#2 + int should give exacly that version (Win32) assert(file.position() == 19 + 13 + 4); - version (linux) + version (Unix) assert(file.position() == 18 + 13 + 4); // we must be at the end of file assert(file.eof()); @@ -2165,7 +2185,7 @@ } } -version (linux) +version (Unix) { static this() { diff -uNr dmd-0.102/src/phobos/std/string.d gdc-0.8/d/phobos/std/string.d --- dmd-0.102/src/phobos/std/string.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/string.d 2004-10-14 02:28:08.000000000 +0200 @@ -19,6 +19,12 @@ // The code is not optimized for speed, that will have to wait // until the design is solidified. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.string; //debug=string; // uncomment to turn on debugging printf's @@ -33,22 +39,40 @@ extern (C) { // Functions from the C library. - int strlen(char *); - int strcmp(char *, char *); - char* strcat(char *, char *); - int memcmp(void *, void *, uint); + version (GNU) // should be: GNU_Use_Builtins / -f[no-]builtins + { + private import gcc.builtins; + alias __builtin_strlen strlen; + alias __builtin_strcmp strcmp; + alias __builtin_strcat strcat; + alias __builtin_memcmp memcmp; + alias __builtin_strcpy strcpy; + alias __builtin_strstr strstr; + alias __builtin_strchr strchr; + alias __builtin_strrchr strrchr; + alias __builtin_memcpy memcpy; + //alias __builtin_memmove memmove;// not in 3.3 + alias __builtin_memset memset; + } + else + { + int strlen(char *); + int strcmp(char *, char *); + char* strcat(char *, char *); + int memcmp(void *, void *, uint); + char *strcpy(char *, char *); + char *strstr(char *, char *); + char *strchr(char *, char); + char *strrchr(char *, char); + void *memcpy(void *, void *, uint); + void *memset(void *, uint, uint); + } + void *memmove(void *, void *, uint); int memicmp(char *, char *, uint); - char *strcpy(char *, char *); int atoi(char *); long atoll(char *); double atof(char *); - char *strstr(char *, char *); - char *strchr(char *, char); - char *strrchr(char *, char); char *memchr(char *, char, uint); - void *memcpy(void *, void *, uint); - void *memmove(void *, void *, uint); - void *memset(void *, uint, uint); int wcslen(wchar *); int wcscmp(wchar *, wchar *); @@ -136,7 +160,7 @@ { result = memicmp(s1, s2, len); } - version (linux) + version (Unix) { for (int i = 0; i < len; i++) { diff -uNr dmd-0.102/src/phobos/std/system.d gdc-0.8/d/phobos/std/system.d --- dmd-0.102/src/phobos/std/system.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/system.d 2004-10-02 19:19:32.000000000 +0200 @@ -4,6 +4,12 @@ * Placed into Public Domain */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + // Information about the target operating system, environment, and CPU module std.system; @@ -16,6 +22,7 @@ { Win32 = 1, // Microsoft 32 bit Windows systems linux, // all linux systems + Unix, // all other } version (Win32) @@ -26,6 +33,10 @@ { Family family = Family.linux; } + else version (Unix) + { + Family family = Family.Unix; + } else { static assert(0); diff -uNr dmd-0.102/src/phobos/std/thread.d gdc-0.8/d/phobos/std/thread.d --- dmd-0.102/src/phobos/std/thread.d 2004-09-21 19:14:58.000000000 +0200 +++ gdc-0.8/d/phobos/std/thread.d 2004-10-10 18:50:42.000000000 +0200 @@ -20,6 +20,12 @@ * distribution. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.thread; //debug=thread; @@ -382,9 +388,442 @@ } +/* ================================ GCC ================================= */ + +version (GNU) +{ + +private import std.c.unix; +private import gcc.threadsem; +private import gcc.gcgcc; +private import gcc.builtins; + +class ThreadError : Error +{ + this(char[] s) + { + super("Thread error: " ~ s); + } +} + +class Thread +{ + this() + { + } + + this(int (*fp)(void *), void *arg) + { + this.fp = fp; + this.arg = arg; + } + + this(int delegate() dg) + { + this.dg = dg; + } + + pthread_t id; + void* stackBottom; + void* stackTop; + + void start() + { + if (state != TS.INITIAL) + error("already started"); + + synchronized (threadLock) + { + for (int i = 0; 1; i++) + { + if (i == allThreads.length) + error("too many threads"); + if (!allThreads[i]) + { allThreads[i] = this; + idx = i; + if (i >= allThreadsDim) + allThreadsDim = i + 1; + break; + } + } + nthreads++; + + state = TS.RUNNING; + int result; + //printf("creating thread x%x\n", this); + result = pthread_create(&id, null, &threadstart, this); + if (result) + { state = TS.TERMINATED; + allThreads[idx] = null; + idx = -1; + error("failed to start"); // BUG: should report errno + } + } // %% changed end of sync region + //printf("t = x%x, id = %d\n", this, id); + } + + int run() + { + if (fp) + return fp(arg); + else if (dg) + return dg(); + } + + void wait() + { + if (this is getThis()) + error("wait on self"); + if (state == TS.RUNNING) + { int result; + void *value; + + result = pthread_join(id, &value); + if (result) + error("failed to wait"); + } + } + + void wait(uint milliseconds) + { + wait(); + /+ not implemented + if (this is getThis()) + error("wait on self"); + if (state == TS.RUNNING) + { DWORD dw; + + dw = WaitForSingleObject(hdl, milliseconds); + } + +/ + } + + enum TS + { + INITIAL, + RUNNING, + TERMINATED + } + + TS getState() + { + return state; + } + + enum PRIORITY + { + INCREASE, + DECREASE, + IDLE, + CRITICAL + } + + void setPriority(PRIORITY p) + { + /+ not implemented + int nPriority; + + switch (p) + { + case PRIORITY.INCREASE: + nPriority = THREAD_PRIORITY_ABOVE_NORMAL; + break; + case PRIORITY.DECREASE: + nPriority = THREAD_PRIORITY_BELOW_NORMAL; + break; + case PRIORITY.IDLE: + nPriority = THREAD_PRIORITY_IDLE; + break; + case PRIORITY.CRITICAL: + nPriority = THREAD_PRIORITY_TIME_CRITICAL; + break; + } + + if (SetThreadPriority(hdl, nPriority) == THREAD_PRIORITY_ERROR_RETURN) + error("set priority"); + +/ + } + + int isSelf() + { + //printf("id = %d, self = %d\n", id, pthread_self()); + return pthread_equal(pthread_self(), id); + } + + static Thread getThis() + { + pthread_t id; + Thread result; + + //printf("getThis(), allThreadsDim = %d\n", allThreadsDim); + synchronized (threadLock) + { + id = pthread_self(); + //printf("id = %d\n", id); + for (int i = 0; i < allThreadsDim; i++) + { + Thread t = allThreads[i]; + //printf("allThreads[%d] = x%x, id = %d\n", i, t, (t ? t.id : 0)); + if (t && pthread_equal(id, t.id)) + { + return t; + } + } + } + printf("didn't find it\n"); + assert(result); + return result; + } + + static Thread[] getAll() + { + return allThreads[0 .. allThreadsDim]; + } + + void pause() + { + if (state == TS.RUNNING) + { int result; + + result = pthread_kill(id, SIGUSR1); + if (result) + error("cannot pause"); + else + flagSuspend.wait(); // wait for acknowledgement + } + else + error("cannot pause"); + } + + void resume() + { + if (state == TS.RUNNING) + { int result; + + result = pthread_kill(id, SIGUSR2); + if (result) + error("cannot resume"); + } + else + error("cannot resume"); + } + + static void pauseAll() + { + if (nthreads > 1) + { + Thread tthis = getThis(); + int npause = 0; + + for (int i = 0; i < allThreadsDim; i++) + { Thread t; + + t = allThreads[i]; + if (t && t !== tthis && t.state == TS.RUNNING) + { int result; + + result = pthread_kill(t.id, SIGUSR1); + if (result) + getThis().error("cannot pause"); + else + npause++; // count of paused threads + } + } + + // Wait for each paused thread to acknowledge + while (npause--) + { + flagSuspend.wait(); + } + } + } + + static void resumeAll() + { + if (nthreads > 1) + { + Thread tthis = getThis(); + + for (int i = 0; i < allThreadsDim; i++) + { Thread t; + + t = allThreads[i]; + if (t && t !== tthis && t.state == TS.RUNNING) + t.resume(); + } + } + } + + static void yield() + { + sched_yield(); + } + + static uint nthreads = 1; + + private: + + static uint allThreadsDim; + static Object threadLock; + static Thread[/*_POSIX_THREAD_THREADS_MAX*/ 100] allThreads; + static Semaphore flagSuspend; + + TS state; + int idx = -1; // index into allThreads[] + int flags = 0; + + int (*fp)(void *); + void *arg; + + int delegate() dg; + + void error(char[] msg) + { + throw new ThreadError(msg); + } + + + /************************************************ + * This is just a wrapper to interface between C rtl and Thread.run(). + */ + + extern (C) static void *threadstart(void *p) + { + Thread t = cast(Thread)p; + int result; + + debug (thread) printf("Starting thread x%x (%d)\n", t, t.idx); + + // Need to set t.id here, because thread is off and running + // before pthread_create() sets it. + t.id = pthread_self(); + + t.stackBottom = getESP(); + try + { + result = t.run(); + } + catch (Object o) + { + printf("Error: "); + o.print(); + result = 1; + } + + debug (thread) printf("Ending thread %d\n", t.idx); + t.state = TS.TERMINATED; + allThreads[t.idx] = null; + t.idx = -1; + nthreads--; + return cast(void*)result; + } + + + /************************************** + * Create a Thread for global main(). + */ + + static this() + { + threadLock = new Object(); + + Thread t = new Thread(); + + t.state = TS.RUNNING; + t.id = pthread_self(); + t.stackBottom = cast(void*) gcc.gcgcc.os_query_stackBottom(); + synchronized (threadLock) + { + assert(!allThreads[0]); + allThreads[0] = t; + allThreadsDim = 1; + t.idx = 0; + } + + /* Install signal handlers so we can suspend/resume threads + */ + + int result; + sigaction_t sigact; + result = sigfillset(&sigact.sa_mask); + if (result) + goto Lfail; + sigact.sa_handler = &pauseHandler; + result = sigaction(SIGUSR1, &sigact, null); + if (result) + goto Lfail; + sigact.sa_handler = &resumeHandler; + result = sigaction(SIGUSR2, &sigact, null); + if (result) + goto Lfail; + + if (! flagSuspend.create()) + goto Lfail; + + return; + + Lfail: + getThis().error("cannot initialize threads"); + } + + /********************************** + * This gets called when a thread gets SIGUSR1. + */ + + extern (C) static void pauseHandler(int sig) + { int result; + + // Save all registers on the stack so they'll be scanned by the GC + __builtin_unwind_init(); + + + assert(sig == SIGUSR1); + // %% moved call to sem_post + + sigset_t sigmask; + result = sigfillset(&sigmask); + assert(result == 0); + result = sigdelset(&sigmask, SIGUSR2); + assert(result == 0); + + Thread t = getThis(); + t.stackTop = getESP(); + t.flags &= ~1; + flagSuspend.signal(); + while (1) + { + sigsuspend(&sigmask); // suspend until SIGUSR2 + if (t.flags & 1) // ensure it was resumeHandler() + break; + } + } + + /********************************** + * This gets called when a thread gets SIGUSR2. + */ + + extern (C) static void resumeHandler(int sig) + { + Thread t = getThis(); + + t.flags |= 1; + } + + static void* getESP() + { + // TODO add builtin for using stack_pointer_rtx + int dummy; + return & dummy + 1; // +1 doesn't help much; also assume stack grows down + } +} + + +} + + /* ================================ linux ================================= */ -version (linux) +else version (linux) { private import std.c.linux.linux; @@ -492,7 +931,6 @@ } } nthreads++; - } state = TS.RUNNING; int result; @@ -504,6 +942,7 @@ idx = -1; error("failed to start"); // BUG: should report errno } + } // %% changed end of sync region //printf("t = x%x, id = %d\n", this, id); } @@ -673,12 +1112,12 @@ else npause++; // count of paused threads } + } - // Wait for each paused thread to acknowledge - while (npause--) - { - sem_wait(&flagSuspend); - } + // Wait for each paused thread to acknowledge + while (npause--) + { + sem_wait(&flagSuspend); } } } @@ -826,7 +1265,7 @@ } assert(sig == SIGUSR1); - sem_post(&flagSuspend); + // %% moved call to sem_post sigset_t sigmask; result = sigfillset(&sigmask); @@ -837,6 +1276,7 @@ Thread t = getThis(); t.stackTop = getESP(); t.flags &= ~1; + sem_post(&flagSuspend); while (1) { sigsuspend(&sigmask); // suspend until SIGUSR2