compiling error "impossible constraint in 'asm'" - gcc

I tried to compile Csmith on my "SunOS sun4v 5.10" system, but I got errors like these:
platform.cpp: In function 'long unsigned int platform_gen_seed()':
platform.cpp:78: error: impossible constraint in 'asm'
Could anyone tell where is the mistake?
#if (TARGET_CPU_powerpc == 1 || TARGET_CPU_powerpc64 == 1)
/*For PPC, got from:
http://lists.ozlabs.org/pipermail/linuxppc-dev/1999-October/003889.html
*/
static unsigned long long read_time(void) {
unsigned long long retval;
unsigned long junk;
__asm__ __volatile__ ("\n\
1: mftbu %1\n\
mftb %L0\n\
mftbu %0\n\
cmpw %0,%1\n\
bne 1b"
: "=r" (retval), "=r" (junk));
return retval;
}
#else
#ifdef WIN32
static unsigned __int64 read_time(void) {
unsigned l, h;
_asm {rdtsc
mov l, eax
mov h, edx
}
return (h << 32) + l ;
}
#else
static long long read_time(void) {
long long l;
asm volatile( "rdtsc\n\t"
: "=A" (l)
);
return l;
}
#endif
#endif
unsigned long platform_gen_seed()
{
return (long) read_time();
}

The problem is that the code you're trying to compile assumes that any target CPU that's not a PowerPC must be an x86 processor. The code simply doesn't doesn't support your SPARC CPU.
Fortunately the code doesn't seem to be critical, it's apparently only used to seed a random number generator, which is then used to create random C programs. The goal being to prevent multiple instances of the program that are started at the same time from generating the same random programs. I'd replace the code with something more portable that's not dependent on the CPU. Something like this:
#ifdef WIN32
unsigned long platform_gen_seed()
{
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
return now.LowPart;
}
#else /* assume something Unix-like */
static unsigned long generic_gen_seed() {
pid_t pid = getpid();
time_t now;
time(&now);
return (unsigned long)(now ^ (pid << 16 | ((pid >> 16) & 0xFFFF)));
}
#ifdef CLOCK_REALTIME
unsigned long platform_gen_seed()
{
struct timespec now, resolution;
if (clock_gettime(CLOCK_REALTIME, &now) == -1
|| clock_getres(CLOCK_REALTIME, &resolution) == -1
|| resolution.tv_sec > 0 || resolution.tv_nsec > 1000000) {
return generic_gen_seed();
}
return (now.tv_nsec / resolution.tv_nsec
+ now.tv_sec * resolution.tv_nsec);
}
#else
unsigned long platform_gen_seed()
{
return generic_gen_seed();
}
#endif /* CLOCK_REALTIME */
#endif /* WIN32 */
The code has been test in isolation on Linux and Windows. It should also work in isolation on Solaris SPARC, but I don't know how well it work in context of the actual program.

Related

problem in synchronization of timer0 and CPU clock cycles

I am a beginner in AVR. I need to sample input at odd intervals of 8 ms. i have used CTC mode for generating 8 ms timer. i used CTC with compare interrupt so that i can get a flag (timer_count) set at every comparison. i.e. after every 8 ms. The 8 ms timer starts on External Interrupt at PIN D0.
when i am checking the input conditions in main loop, due to large difference in frequency of main controller (18.432 MHz) and 8 ms timer, i am unable to sample inputs correctly. Can anyone tell me any other method to do this. The code is pasted here for reference.
#include <mega128.h>
#include <stdio.h>
#include <stdlib.h>
#define CHECK_BIT(ADDRESS,BIT) (ADDRESS & (1<<BIT))
#define SET_BIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define CLEAR_BIT(ADDRESS,BIT) (ADDRESS &= (~(1<<BIT)))
#define TGL_BIT(ADDRESS, BIT) (ADDRESS ^= (1<<BIT))
volatile unsigned int flag;
volatile unsigned int timer_count=0;
volatile unsigned int frequency_979_sense;
volatile unsigned int frequency_885_sense;
volatile unsigned int frequency_933_sense;
volatile unsigned int flag_979_received;
volatile unsigned int flag_885_received;
volatile unsigned int data;
volatile unsigned int i;
volatile unsigned char SOP_valid;
volatile unsigned int previous_state=0;
volatile unsigned int current_state=0;
// Timer 0 output compare interrupt service routine
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
timer_count++;
}
void init_timer0()
{
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 18.000 kHz
// Mode: CTC top=OCR0
// OC0 output: toggle output on compare match
ASSR=0x00;
TCCR0=0x1F;
TCNT0=0x00;
OCR0=0x90;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x02;
}
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
if ((CHECK_BIT(PIND,4)==0) & (CHECK_BIT(PIND,5)==0))
{
init_timer0();
flag=1;
CLEAR_BIT(EIMSK,0);
CLEAR_BIT(EIFR,0);
}
}
void main(void)
{
// Port D initialization
PORTD=0xFF;
DDRD=0x00;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Rising Edge
EICRA=0x03;
EICRB=0x00;
EIMSK=0x01;
EIFR=0x01;
// Global enable interrupts
#asm("sei")
while (1)
{
while (timer_count > 0 & timer_count<32)
{
if (timer_count%2==1)
{
frequency_979_sense= CHECK_BIT(PIND,0);
frequency_885_sense= CHECK_BIT(PIND,4);
frequency_933_sense= CHECK_BIT(PIND,5);
if ((frequency_979_sense != 0) && (frequency_885_sense == 0) && (frequency_933_sense == 0) && (flag_885_received==0 || flag_885_received== 8))
{
flag_979_received++;
SET_BIT(data,i);
}
if ((frequency_979_sense == 0) && (frequency_885_sense != 0) && (frequency_933_sense == 0) && (flag_979_received==6))
{
flag_885_received++;
SET_BIT(data,i);
}
else
{
flag_979_received=0;
flag_885_received=0;
frequency_979_sense=0;
frequency_885_sense=0;
frequency_933_sense=0;
data=0;
TCCR0=0x00;
TIMSK=0x00;
timer_count=0;
i=0;
SET_BIT(EIMSK,0);
SET_BIT(EIFR,0);
}
}
i++;
}
if (data==65535)
{
SOP_valid=1;
}
}
}

Not able to send info to LCD

I studied this code in one of the youtube tutorials, I cannot send info to LCD, the program shows error, the error which I keep getting is
Initializing argument 1 of 'void Send_A_String(char*)' [-fpermissive]
initializing argument 3 of 'void Send_An_IntegerToMrLCD(uint8_t, uint8_t, int, char)' [-fpermissive]
invalid conversion from 'char' to 'char*' [-fpermissive]
invalid conversion from 'char*' to 'int' [-fpermissive]
Below is the header file for LCD - MrLCD.h
#ifndef MrLCD
#define MrLCD
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#define MrLCDsCrib PORTB
#define DataDir_MrLCDsCrib DDRB
#define MrLCDsControl PORTD
#define DataDir_MrLCDsControl DDRD
#define LightSwitch 5
#define ReadWrite 7
#define BiPolarMood 2
char firstColumnPositionsForMrLCD[4] = {0, 64, 20, 84};
void Check_IF_MrLCD_isBusy(void);
void Peek_A_Boo(void);
void Send_A_Command(unsigned char command);
void Send_A_Character(unsigned char character);
void Send_A_String(char *StringOfCharacters);
void initializeMrLCD(void);
void GotoMrLCDsLocation(uint8_t x, uint8_t y);
void Send_A_StringToMrLCDWithLocation(uint8_t x, uint8_t y, char *StringOfCharacters);
void Send_An_IntegerToMrLCD(uint8_t x, uint8_t y, int IntegerToDisplay, char NumberOfDigits);
void Check_IF_MrLCD_isBusy()
{
DataDir_MrLCDsCrib = 0;
MrLCDsControl |= 1<<ReadWrite;
MrLCDsControl &= ~1<<BiPolarMood;
while (MrLCDsCrib >= 0x80)
{
Peek_A_Boo();
}
DataDir_MrLCDsCrib = 0xFF;
}
void Peek_A_Boo()
{
MrLCDsControl |= 1<<LightSwitch;
asm volatile ("nop");
asm volatile ("nop");
MrLCDsControl &= ~1<<LightSwitch;
}
void Send_A_Command(unsigned char command)
{
Check_IF_MrLCD_isBusy();
MrLCDsCrib = command;
MrLCDsControl &= ~ ((1<<ReadWrite)|(1<<BiPolarMood));
Peek_A_Boo();
MrLCDsCrib = 0;
}
void Send_A_Character(unsigned char character)
{
Check_IF_MrLCD_isBusy();
MrLCDsCrib = character;
MrLCDsControl &= ~ (1<<ReadWrite);
MrLCDsControl |= 1<<BiPolarMood;
Peek_A_Boo();
MrLCDsCrib = 0;
}
void Send_A_String(char *StringOfCharacters)
{
while(*StringOfCharacters > 0)
{
Send_A_Character(*StringOfCharacters++);
}
}
void initializeMrLCD()
{
DataDir_MrLCDsControl |= 1<<LightSwitch | 1<<ReadWrite | 1<<BiPolarMood;
_delay_ms(15);
Send_A_Command(0x01); //Clear Screen 0x01 = 00000001
_delay_ms(2);
Send_A_Command(0x38);
_delay_us(50);
Send_A_Command(0b00001110);
_delay_us(50);
}
void GotoMrLCDsLocation(uint8_t x, uint8_t y)
{
Send_A_Command(0x80 + firstColumnPositionsForMrLCD[y-1] + (x-1));
}
void Send_A_StringToMrLCDWithLocation(uint8_t x, uint8_t y, char *StringOfCharacters)
{
GotoMrLCDsLocation(x, y);
Send_A_String(*StringOfCharacters);
}
void Send_An_IntegerToMrLCD(uint8_t x, uint8_t y, int IntegerToDisplay, char NumberOfDigits)
{
char StringToDisplay[NumberOfDigits];
itoa(IntegerToDisplay, StringToDisplay, 10);
Send_A_StringToMrLCDWithLocation(x, y, StringToDisplay);
Send_A_String(" ");
}
#endif
And in the simplest of programs in the main file, if I try to call these functions in the header file like Send_A_StringToMrLCDWithLocation or Send_An_IntegerToMrLCD... The program shows error...
You need to move all this code into a C file, i.e. MrLCD.c because that is where the code is instantiated.
You have not included the .c file where you call these functions, but the error appears to say that you are calling the functions with the wrong type of variables.
You are calling void Send_A_String(char*) with a char rather than a pointer to a string.
You are calling void Send_An_IntegerToMrLCD(uint8_t, uint8_t, int, char) with a char pointer (string) rather than an int in the third parameter.

Warning: cast to/from pointer from/to integer of different size

I'm learning Pthreads. My code executes the way I want it to, I'm able to use it. But it gives me a warning on compilation.
I compile using:
gcc test.c -o test -pthread
with GCC 4.8.1. And I get the warning
test.c: In function ‘main’:
test.c:39:46: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
pthread_create(&(tid[i]), &attr, runner, (void *) i);
^
test.c: In function ‘runner’:
test.c:54:22: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
int threadnumber = (int) param;
^
This error comes for the following code:
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#define MAX_THREADS 10
int sum; /* this data is shared by the thread(s) */
void *runner(void * param);
int main(int argc, char *argv[])
{
int num_threads, i;
pthread_t tid[MAX_THREADS]; /* the thread identifiers */
pthread_attr_t attr; /* set of thread attributes */
if (argc != 2) {
fprintf(stderr, "usage: test <integer value>\n");
exit(EXIT_FAILURE);
}
if (atoi(argv[1]) <= 0) {
fprintf(stderr,"%d must be > 0\n", atoi(argv[1]));
exit(EXIT_FAILURE);
}
if (atoi(argv[1]) > MAX_THREADS) {
fprintf(stderr,"%d must be <= %d\n", atoi(argv[1]), MAX_THREADS);
exit(EXIT_FAILURE);
}
num_threads = atoi(argv[1]);
printf("The number of threads is %d\n", num_threads);
/* get the default attributes */
pthread_attr_init(&attr);
/* create the threads */
for (i=0; i<num_threads; i++) {
pthread_create(&(tid[i]), &attr, runner, (void *) i);
printf("Creating thread number %d, tid=%lu \n", i, tid[i]);
}
/* now wait for the threads to exit */
for (i=0; i<num_threads; i++) {
pthread_join(tid[i],NULL);
}
return 0;
}
/* The thread will begin control in this function */
void *runner(void * param)
{
int i;
int threadnumber = (int) param;
for (i=0; i<1000; i++) printf("Thread number=%d, i=%d\n", threadnumber, i);
pthread_exit(0);
}
How can I fix this warning?
A quick hacky fix might just to cast to long instead of int. On a lot of systems, sizeof(long) == sizeof(void *).
A better idea might be to use intptr_t.
int threadnumber = (intptr_t) param;
and
pthread_create(&(tid[i]), &attr, runner, (void *)(intptr_t)i);
pthread_create(&(tid[i]), &attr, runner, (void *) i);
You are passing the local variable i as an argument for runner, sizeof(void*) == 8 and sizeof(int) == 4 (64 bits).
If you want to pass i, you should wrap it as a pointer or something:
void *runner(void * param) {
int id = *((int*)param);
delete param;
}
int tid = new int; *tid = i;
pthread_create(&(tid[i]), &attr, runner, tid);
You may just want i, and in that case, the following should be safe (but far from recommended):
void *runner(void * param) {
int id = (int)param;
}
pthread_create(&(tid[i]), &attr, runner, (void*)(unsigned long long)(i));
I was also getting the same warning. So to resolve my warning I converted int to long and then this warning just vanished. And about the warning "cast to pointer from integer of different size" you can leave this warning because a pointer can hold the value of any variable because pointer in 64x is of 64 bit and in 32x is of 32 bit.
Try passing
pthread_create(&(tid[i]), &attr, runner, (void*)&i);

Porting C++ project from VS 6.0 to VS 2010 brought to slower code

I ported one project from Visual C++ 6.0 to VS 2010 and found that a critical part of the code (scripting engine) now runs in about three times slower than in was before.
After some research I managed to extract code fragment which seems to cause the slowdown. I minimized it as much as possible, so it ill be easier to reproduce the problem.
The problem is reproduced when assigning a complex class (Variant) which contains another class (String), and the union of several other fields of simple types.
Playing with the example I discovered more "magic":
1. If I comment one of unused (!) class members, the speed increases, and the code finally runs faster than those complied with VS 6.2
2. The same is true if I remove the "union" wrapper"
3. The same is true event if change the value of the filed from 1 to 0
I have no idea what the hell is going on.
I have checked all code generation and optimization switches, but without any success.
The code sample is below:
On my Intel 2.53 GHz CPU this test, compiled under VS 6.2 runs 1.0 second.
Compiled under VS 2010 - 40 seconds
Compiled under VS 2010 with "magic" lines commented - 0.3 seconds.
The problem is reproduces with any optimization switch, but the "Whole program optimization" (/GL) should be disabled. Otherwise this too smart optimizer will know that out test actually does nothing, and the test will run 0 seconds.
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
class String
{
public:
char *ptr;
int size;
String() : ptr(NULL), size( 0 ) {};
~String() {if ( ptr != NULL ) free( ptr );};
String& operator=( const String& str2 );
};
String& String::operator=( const String& string2 )
{
if ( string2.ptr != NULL )
{
// This part is never called in our test:
ptr = (char *)realloc( ptr, string2.size + 1 );
size = string2.size;
memcpy( ptr, string2.ptr, size + 1 );
}
else if ( ptr != NULL )
{
// This part is never called in our test:
free( ptr );
ptr = NULL;
size = 0;
}
return *this;
}
struct Date
{
unsigned short year;
unsigned char month;
unsigned char day;
unsigned char hour;
unsigned char minute;
unsigned char second;
unsigned char dayOfWeek;
};
class Variant
{
public:
int dataType;
String valStr; // If we comment this string, the speed is OK!
// if we drop the 'union' wrapper, the speed is OK!
union
{
__int64 valInteger;
// if we comment any of these fields, unused in out test, the speed is OK!
double valReal;
bool valBool;
Date valDate;
void *valObject;
};
Variant() : dataType( 0 ) {};
};
void TestSpeed()
{
__int64 index;
Variant tempVal, tempVal2;
tempVal.dataType = 3;
tempVal.valInteger = 1; // If we comment this string, the speed is OK!
for ( index = 0; index < 200000000; index++ )
{
tempVal2 = tempVal;
}
}
int main(int argc, char* argv[])
{
int ticks;
char str[64];
ticks = GetTickCount();
TestSpeed();
sprintf( str, "%.*f", 1, (double)( GetTickCount() - ticks ) / 1000 );
MessageBox( NULL, str, "", 0 );
return 0;
}
This was rather interesting. First I was unable to reproduce the slow down in release build, only in debug build. Then I turned off SSE2 optimizations and got the same ~40s run time.
The problem seems to be in the compiler generated copy assignment for Variant. Without SSE2 it actually does a floating point copy with fld/fstp instructions because the union contains a double. And with some specific values this apparently is a really expensive operation. The 64-bit integer value 1 maps to 4.940656458412e-324#DEN which is a denormalized number and I believe this causes problems. When you leave tempVal.valInteger uninitialized it may contain a value that works faster.
I did a small test to confirm this:
union {
uint64_t i;
volatile double d1;
};
i = 0xcccccccccccccccc; //with this value the test takes 0.07 seconds
//i = 1; //change to 1 and now the test takes 36 seconds
volatile double d2;
for(int i=0; i<200000000; ++i)
d2 = d1;
So what you could do is define your own copy assignment for Variant that just does a simple memcpy of the union.
Variant& operator=(const Variant& rhs)
{
dataType = rhs.dataType;
union UnionType
{
__int64 valInteger;
double valReal;
bool valBool;
Date valDate;
void *valObject;
};
memcpy(&valInteger, &rhs.valInteger, sizeof(UnionType));
valStr = rhs.valStr;
return *this;
}

No-overflow cast on x64

I have an existing C codebase that works on x86.
I'm now compiling it for x64.
What I'd like to do is cast a size_t to a DWORD, and throw an exception if there's a loss of data.
Q: Is there an idiom for this?
Here's why I'm doing this:
A bunch of Windows APIs accept DWORDs as arguments, and the code currently assumes sizeof(DWORD)==sizeof(size_t). That assumption holds for x86, but not for x64. So when compiling for x64, passing size_t in place of a DWORD argument, generates a compile-time warning.
In virtually all of these cases the actual size is not going to exceed 2^32. But I want to code it defensively and explicitly.
This is my first x64 project, so... be gentle.
see boost::numeric_cast
http://www.boost.org/doc/libs/1_33_1/libs/numeric/conversion/doc/numeric_cast.html
I just defined a function to perform the cast.
I included an assert-like behavior to insure I'm not silently rubbishing pointers.
DWORD ConvertSizeTo32bits(size_t sz, char *file, int line)
{
if (!(0 <= sz && sz <= INT32_MAX)) {
EmitLogMessage("Invalid Pointer size: %d file(%s) line(%d)",
sz, file, line);
ExitProcess( 0 );
}
return (DWORD) sz;
}
#define size_t_to_DWORD(st,dw) if ((DWORD)(st) != st) RaiseException(exLossOfData, 0, 0, NULL); else dw = (DWORD)(st)
size_t st;
DWORD dw;
st = 0xffffffff;
size_t_to_DWORD(st,dw); // this succeeds
st = 0xffffffff1;
size_t_to_DWORD(st,dw); // this throws
EDIT:
Or better yet, do this so you can use it in an expression:
DWORD MyRaiseException()
{
RaiseException(1, 0, 0, NULL);
return 0;
}
#define size_t_to_DWORD(st) (DWORD)(st) != (st) ? MyRaiseException() : (DWORD)(st)
void main(void)
{
size_t st;
DWORD dw;
st = 0xffffffff1;
dw = size_t_to_DWORD(st);
printf("%u %u\n", st, dw);
}

Resources