I am trying to compile this code:
#include <sys/types.h>
#include <argp.h>
#include <stdlib.h>
#include <xmmintrin.h>
__attribute__((noinline)) void vadd(float *a, float *b, size_t size)
{
size_t i;
for (i=0; i<size; i+=4)
{
__m128 v1 = _mm_load_ps(a + i); //loads up 4 floats into a __m128
__m128 v2 = _mm_load_ps(b + i); //loads up 4 floats into a __m128
__m128 v3 = _mm_add_ps(v1, v2);
_mm_store_ps(a+i, v3);
}
}
__attribute__((noinline)) void sadd(float *a, float *b, size_t size)
{
size_t i;
for(i=0; i<size; i++)
{
a[i] += b[i];
}
}
int main (void)
{
size_t size = 300000000;
float *a = (float *)calloc(size, sizeof(float));
float *b = (float *)calloc(size, sizeof(float));
vadd(a, b, size);
sadd(a, b, size);
}
I am receiving this error:
/usr/lib/gcc/i486-linux-gnu/4.8/include/mmintrin.h: In function ‘_mm_cvtsi32_si64’:
/usr/lib/gcc/i486-linux-gnu/4.8/include/mmintrin.h:61:3: error: can’t convert between vector values of different size
return (__m64) __builtin_ia32_vec_init_v2si (__i, 0);
Is there a way to work that out?
Related
I am studying CS50 Pset 4.
As I know, I type the same word eg: "Emma". When I compare them, they will not the same coz they are storing it in 2 different addresses in the memory.
But I am confused about integer, they are also storing in 2 different addresses in the memory even I input the same number. But they are the same when I compare them.
Can someone tell me what I misunderstood?
#include <stdio.h>
#include <cs50.h>
int main(void)
{
int i = get_int("i: ");
int j = get_int("j: ");
char *s = get_string("s: ");
char *t = get_string("t: ");
if (i == j)
{
printf("Same\n");
printf("%p\n", &i);
printf("%p\n", &j);
}
else
{
printf("Different\n");
printf("%p\n", &i);
printf("%p\n", &j);
}
if (s == t)
{
printf("Same\n");
printf("%p\n", &s);
printf("%p\n", &t);
}
else
{
printf("Different\n");
printf("%p\n", &s);
printf("%p\n", &t);
}
}
You can't compare two strings using ==. In order to do so sucessfully, you either use a function called strcmp, or create a loop iterating over all characters in the string. (include #include <string.h> in order to make this work. This is what your code should look like:
#include <stdio.h>
#include <cs50.h>
#include <string.h>
int main(void)
{
int i = get_int("i: ");
int j = get_int("j: ");
char *s = get_string("s: ");
char *t = get_string("t: ");
if (i == j)
{
printf("Same\n");
printf("%p\n", &i);
printf("%p\n", &j);
}
else
{
printf("Different\n");
printf("%p\n", &i);
printf("%p\n", &j);
}
if (strcmp(s, t) == 0)
{
printf("Same\n");
printf("%p\n", &s);
printf("%p\n", &t);
}
else
{
printf("Different\n");
printf("%p\n", &s);
printf("%p\n", &t);
}
}
strcmp takes input two string, and outputs 0 if they're the same, and any other number if not. (Hope this helps!!:))
The secondexample below is what I would like to achieve in the firstcode written up. I want to ask how many 'dati' wants to insert then I have to do a malloc and I want to ask and save each dato of every struct so, firstly cdfM of the struct maestra and so on... How can I do that? How should I create the array with the malloc and how what should I do to save all the infos?
thx
#include <stdio.h>
#include <stdlib.h>
#define MAX 30
struct dati{
struct maestra{
char cdfM[MAX];
char nomeM[MAX];
char cognomeM[MAX];
char specializzazioneM[MAX];
}
struct classe{
int id;
char nome[MAX];
char colore[MAX];
}
struct insegnamento{
int idclasseI;
char cfmaestra[MAX];
}
struct bambino{
char cdfB[MAX];
char nomeB[MAX];
char cognomeB[MAX];
char dataNascita[MAX];
int idclasseB;
char dataIscrizione[MAX];
}
}
int main () {
struct dati *p,*q,*r,*s;
struct maestra **p;
struct classe **q;
struct insegnamento **r;
struct bambino **s;
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#define MAX 30
struct studente{
char nomeCognome[MAX];
int numeroMatricola;
float percentualeEP;
};
int main() {
struct studente *p;
int m, i;
printf("Quanti studenti devi inserire: \n");
scanf("%d", &m);
p = malloc(m*sizeof(int));
for (i=0; i < m; i++){
printf("Inserisci i dati dell'utente numero %d\n",i+1);
printf("Inserisci il nome cognome: \n");
scanf(" ");
fgets((p+i)->nomeCognome, MAX, stdin);
printf("Inserisci la matricola: \n");
scanf("%d",&(p+i)->numeroMatricola);
printf("Inserisci la percentuale di esami passati: \n");
scanf("%f", &(p+i)->percentualeEP);
}
I've found nice example how to create thunk for closure, but it's 32-bit version:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
struct env {
int x;
};
struct __attribute__((packed)) thunk {
unsigned char push;
struct env * env_addr;
unsigned char call;
signed long call_offset;
unsigned char add_esp[3];
unsigned char ret;
};
struct thunk default_thunk = {0x68, 0, 0xe8, 0, {0x83, 0xc4, 0x04}, 0xc3};
typedef void (* cfunc)();
struct thunk * make_thunk(struct env * env, void * code)
{
struct thunk * thunk = (struct thunk *)mmap(0,sizeof(struct thunk), PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
*thunk = default_thunk;
thunk->env_addr = env;
thunk->call_offset = code - (void *)&thunk->add_esp[0]; // Pretty!
mprotect(thunk,sizeof(struct thunk), PROT_EXEC);
return thunk;
}
void block(struct env * env) {
env->x += 1;
printf ("block: x is %d\n", env->x);
}
cfunc foo (int x)
{
struct env * env = (struct env *)malloc(sizeof(struct env));
env->x = x;
printf ("x is %d\n",env->x);
return (cfunc)make_thunk(env,(void *)&block);
}
int main() {
cfunc c = foo(5);
c();
c();
}
How can I rewrite it for 64-bit version?
I'm using Linux x86_64. I've been able to cross-compile it with gcc -m32, which worked perfectly.
The code below is designed to be used with GCC on Linux and should support 32 and 64 bit compilation.
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
struct env {
int x;
};
#if __x86_64__
struct __attribute__((packed)) thunk {
unsigned char mov[2];
struct env * env_addr;
unsigned char movrax[2];
void (*call_address)();
unsigned char jmp[2];
};
struct thunk default_thunk = {{0x48, 0xbf}, 0x0, {0x48, 0xb8}, 0x0, {0xff, 0xe0} };
#elif __i386__
struct __attribute__((packed)) thunk {
unsigned char push;
struct env * env_addr;
unsigned char call;
signed long call_offset;
unsigned char add_esp[3];
unsigned char ret;
};
struct thunk default_thunk = {0x68, 0, 0xe8, 0, {0x83, 0xc4, 0x04}, 0xc3};
#else
#error Architecture unsupported
#endif
typedef void (* cfunc)();
struct thunk * make_thunk(struct env * env, void * code)
{
struct thunk * thunk = (struct thunk *)mmap(0,sizeof(struct thunk),
PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
*thunk = default_thunk;
#if __x86_64__
thunk->env_addr = env;
thunk->call_address = code; /* Pretty! */
#else
thunk->env_addr = env;
thunk->call_offset = code - (void *)&thunk->add_esp[0]; /* Pretty! */
#endif
mprotect(thunk,sizeof(struct thunk), PROT_EXEC);
return thunk;
}
void block(struct env * env) {
env->x += 1;
printf ("block: x is %d\n", env->x);
}
cfunc foo (int x)
{
struct env * env = (struct env *)malloc(sizeof(struct env));
env->x = x;
printf ("x is %d\n",env->x);
return (cfunc)make_thunk(env,(void *)&block);
}
int main() {
cfunc c = foo(5);
c();
c();
return 0;
}
Assuming that the OS is using System V 64bit ABI (Which Linux uses) calling convention then the first parameter that will be passed to the function will be in register %rdi. Then we just have to mov the environment address (env_addr) to %rdi and then do a call. The call uses an indirect jump to an absolute location through %rax. So the instruction sequence looks like (at&t syntax):
mov $env_addr, %rdi
movabs $call_pointer, %rax
jmpq *%rax # Tail call instead of call/retq
How would one go about encoding this chunk of C code in a .chs file so that c2hs can transform it to something relatively nice?
typedef enum {
MONOME_BUTTON_UP = 0x00,
MONOME_BUTTON_DOWN = 0x01,
MONOME_ENCODER_DELTA = 0x02,
MONOME_ENCODER_KEY_UP = 0x03,
MONOME_ENCODER_KEY_DOWN = 0x04,
MONOME_TILT = 0x05,
/* update this if you add event types */
MONOME_EVENT_MAX = 0x06
} monome_event_type_t;
typedef struct monome monome_t; /* opaque data type */
typedef struct monome_event monome_event_t;
typedef void (*monome_event_callback_t)
(const monome_event_t *event, void *data);
struct monome_event {
monome_t *monome;
monome_event_type_t event_type;
/* __extension__ for anonymous unions in gcc */
__extension__ union {
struct {
unsigned int x;
unsigned int y;
} grid;
struct {
unsigned int number;
int delta;
} encoder;
struct {
unsigned int sensor;
int x;
int y;
int z;
} tilt;
};
};
How about this: change the code so that you name the members. The layout in memory is the same so that it will be binary compatible. You would have to do this patch for each version of the lib.
struct monome_event {
monome_t *monome;
monome_event_type_t event_type;
/* __extension__ for anonymous unions in gcc */
__extension__ union {
struct me_grid {
unsigned int x;
unsigned int y;
} grid;
struct me_encoder {
unsigned int number;
int delta;
} encoder;
struct me_tilt {
unsigned int sensor;
int x;
int y;
int z;
} tilt;
};
};
I wanted to create a quick quadtree in c++ but found that when I change a value of a struct within a function the value reverts. Also within the recursive function I wont some of the data created to be global. How do I do this?
#include <iostream>
struct a{
unsigned int value;
struct a * leaf[4];
};
void build(struct a root, unsigned int depth){
depth++;
root.value = 0;
struct a leaf0;
root.leaf[0] = &leaf0;
struct a leaf1;
root.leaf[1] = &leaf1;
struct a leaf2;
root.leaf[2] = &leaf2;
struct a leaf3;
root.leaf[3] = &leaf3;
if (depth != 5) {
build(*root.leaf[0], depth);
build(*root.leaf[1], depth);
build(*root.leaf[2], depth);
build(*root.leaf[3], depth);
}
}
int main(int argc, const char * argv[])
{
struct a root;
root.value = 364;
build(root, 0);
std::cout << root.value;
return 0;
}
You must pass the address of the struct to your function (which should accept a pointer to the struct):
void build(struct a *root, unsigned int depth) {
...
}
int main(int argc, const char * argv[])
...
build(&root, 0);
}