//really hacky ~ //Isn't this now obsolete anyway ? (constprop pass should include it ..) // -> constprop has some small stability issues still, not ready to be used on ip/bios fully yet void PromoteConstAddress(RuntimeBlockInfo* blk) { bool is_const=false; u32 value; total_blocks++; for (size_t i=0;i<blk->oplist.size();i++) { shil_opcode* op=&blk->oplist[i]; if (is_const && op->op==shop_readm && op->rs1.is_reg() && op->rs1._reg==reg_r0) { u32 val=value; if (op->rs3.is_imm()) { val+=op->rs3._imm; op->rs3=shil_param(); } op->rs1=shil_param(FMT_IMM,val); } if (op->op==shop_mov32 && op->rs1.is_imm() && isdst(op,reg_r0) ) { is_const=true; value=op->rs1._imm; } else if (is_const && (isdst(op,reg_r0) || op->op==shop_ifb || op->op==shop_sync_sr) ) is_const=false; } }
/** Calculate the current TZ offset in seconds **/ int local_tzoffset(TIMESTAMP t) { #ifdef USE_TS_CACHE static old_t = 0; static old_tzoffset = 0; if (old_t==0 || old_t!=t) { old_tzoffset = tzoffset + isdst(t)?3600:0; old_t = t; } return old_tzoffset; #else return tzoffset + (isdst(t)?3600:0); #endif }
/** * Find first daylight savings time transition after clock. * * @param clock system time from which to begin search * @return system time of next DST transition */ time_t nextdst(time_t clock) { int dst; // Whether daylight savings applies at clock int stepsize = 600; // Try each 10-minute interval if (dsttype() == 0) { std::cerr << "Daylight savings not in effect" << std::endl; return -1; } dst = isdst(clock); // Determine current DST status clock -= (clock % 600); // Round down to nearest ten minutes while (isdst(clock) == dst) // Find the next time where DST is different { clock += stepsize; // Try stepsize minutes later } return clock; }
/** * Determines whether daylight savings time applies at current time. * * @return >0 if DST applies, 0 if not */ int isdst() { time_t now; now = time(0); if (now < 0) { perror("Unable to determine system time"); return -1; } return isdst(now); }
/** Convert a datetime struct into a GMT timestamp **/ TIMESTAMP mkdatetime(DATETIME *dt) { TIMESTAMP ts; int n; if(dt == NULL){ return TS_INVALID; } /* start with year */ timestamp_year(0,NULL); /* initializes tszero */ if(dt->year < YEAR0 || dt->year >= YEAR0 + sizeof(tszero) / sizeof(tszero[0]) ){ return TS_INVALID; } ts = tszero[dt->year-YEAR0]; if(dt->month > 12 || dt->month < 1) { output_fatal("Invalid month provided in datetime"); return TS_INVALID; } else if(dt->day > daysinmonth[dt->month-1] || dt->day < 1) { if(ISLEAPYEAR(dt->year) && dt->month == 2 && dt->day == 29){ ; } else { output_fatal("Invalid day provided in datetime"); return TS_INVALID; } } /* add month */ for (n=1; n<dt->month; n++){ if(ISLEAPYEAR(dt->year) && n == 2){ ts += (daysinmonth[n - 1] + 1) * DAY; } else { ts += (daysinmonth[n - 1]) * DAY; } // ts += (daysinmonth[n - 1] + (n == 2 && ISLEAPYEAR(dt->year) ? 1 : 0)) * DAY; } if(dt->hour < 0 || dt->hour > 23 || dt->minute < 0 || dt->minute > 60 || dt->second < 0 || dt->second > 62){ output_fatal("Invalid time of day provided in datetime"); return ts; } /* add day, hour, minute, second, usecs */ ts += (dt->day - 1) * DAY + dt->hour * HOUR + dt->minute * MINUTE + dt->second * SECOND + dt->nanosecond/1.0e9; if(dt->tz[0] == 0){ strcpy(dt->tz, (isdst(ts) ? tzdst : tzstd)); } /* adjust for GMT (or unspecified) */ if (strcmp(dt->tz, "GMT") == 0){ return ts; } else if(strcmp(dt->tz, tzstd) == 0 || ((strcmp(dt->tz, "")==0 && !isdst(ts) && (ts < dststart[dt->year - YEAR0] || ts >= dstend[dt->year - YEAR0])))){ /* adjust to standard local time */ return ts + tzoffset; } else if(strcmp(dt->tz, tzdst) == 0 || ((strcmp(dt->tz, "")==0 && !isdst(ts) && ts >= dststart[dt->year - YEAR0] && ts < dstend[dt->year - YEAR0]))){ /* adjust to daylight local time */ return ts + tzoffset - HOUR; } else { /* not a valid timezone */ return TS_INVALID; } return TS_INVALID; // heading off 'no return path' warnings }
/** Converts a GMT timestamp to local datetime struct Adjusts to TZ if possible **/ int local_datetime(TIMESTAMP ts, DATETIME *dt) { int64 n; TIMESTAMP rem = 0; TIMESTAMP local; int tsyear; #ifdef USE_TS_CACHE /* allow caching */ static TIMESTAMP old_ts =0; static DATETIME old_dt; #endif if( ts == TS_NEVER || ts==TS_ZERO ) return 0; if( dt==NULL || ts<TS_ZERO || ts>TS_MAX ) /* no buffer or timestamp out of range */ { output_error("local_datetime(ts=%lli,...): invalid local_datetime request",ts); return 0; } #ifdef USE_TS_CACHE /* check cache */ if (old_ts == ts && old_ts!=0) memcpy(dt,&old_dt,sizeof(DATETIME)); else old_ts = 0; #endif local = LOCALTIME(ts); tsyear = timestamp_year(local, &rem); if (rem < 0) { // DPC: note that as of 3.0, the clock is initialized by default, so this error can only // occur when an invalid timestamp is being converted to local time. It should no // longer occur as a result of a missing clock directive. //THROW("local_datetime(ts=%lli, ...): invalid timestamp cannot be converted to local time", ts); /* TROUBLESHOOT This is the result of an internal core or module coding error which resulted in an invalid UTC clock time being converted to local time. */ output_error("local_datetime(ts=%lli,...): invalid local_datetime request",ts); return 0; } if(ts < TS_ZERO && ts > TS_MAX){ /* timestamp out of range */ return 0; } if(ts == TS_NEVER){ return 0; } /* ts is valid */ dt->timestamp = ts; /* DST? */ dt->is_dst = (tzvalid && isdst(ts)); /* compute year */ dt->year = tsyear; /* yearday and weekday */ dt->yearday = (unsigned short)(rem / DAY); dt->weekday = (unsigned short)((local / DAY + DOW0 + 7) % 7); /* compute month */ dt->month = 0; n = daysinmonth[0] * DAY; while(rem >= n){ rem -= n; /* subtract n ticks from ts */ dt->month++; /* add to month */ if(dt->month == 12){ dt->month = 0; ++dt->year; } n = (daysinmonth[dt->month] + ((dt->month == 1 && ISLEAPYEAR(dt->year)) ? 1:0)) * 86400 * TS_SECOND; if(n < 86400 * 28){ /**/ output_fatal("Breaking an infinite loop in local_datetime! (ts = %"FMT_INT64"ds", ts); /* TROUBLESHOOT An internal protection against infinite loops in the time calculation module has encountered a critical problem. This is often caused by an incorrectly initialized timezone system, a missing timezone specification before a timestamp was used, or a missing timezone localization in your system. Correct the timezone problem and try again. */ return 0; } } dt->month++; /* Jan=1 */ /* compute day */ dt->day = (unsigned short)(rem / DAY + 1); rem %= DAY; /* compute hour */ dt->hour = (unsigned short)(rem / HOUR); rem %= HOUR; /* compute minute */ dt->minute = (unsigned short)(rem / MINUTE); rem %= MINUTE; /* compute second */ dt->second = (unsigned short)rem / TS_SECOND; rem %= SECOND; /* compute nanosecond */ dt->nanosecond = (unsigned int)(rem * 1e9); /* determine timezone */ strncpy(dt->tz, tzvalid ? (dt->is_dst ? tzdst : tzstd) : "GMT", sizeof(dt->tz)); /* timezone offset in seconds */ dt->tzoffset = tzoffset - (isdst(dt->timestamp)?3600:0); #ifdef USE_TS_CACHE /* cache result */ old_ts = ts; memcpy(&old_dt,dt,sizeof(old_dt)); #endif return 1; }