int main(int argc, const char *argv[]) { queue_t* a; int data; int i; a = (queue_t*)malloc(sizeof(queue_t)); new_queue(a, 10); print_queue(a); pushq(a, 2); print_queue(a); popq(a, &data); print_queue(a); pushq(a, 3); print_queue(a); for(i = 0; i < a->size + 3; i++) { pushq(a, i); print_queue(a); } for(i = 0; i < a->size + 3; i++) { popq(a, &data); print_queue(a); printf("data: %d\n", data); } del_queue(a); free(a); return 0; }
static void assign(Node *n) { Node *l, *r; int op; op = n->Assign.op; l = n->Assign.l; r = n->Assign.r; if(op == '=') { expr(r); pushq("rax"); addr(l); popq("rcx"); if(!isptr(l->type) && !isitype(l->type) && !isstruct(l->type)) errorf("unimplemented assign\n"); store(l->type); outi("movq %%rcx, %%rax\n"); return; } addr(l); pushq("rax"); load(l->type); pushq("rax"); expr(r); outi("movq %%rax, %%rcx\n"); popq("rax"); /* XXX this type is not correct for comparison ops works anyway, but should be changed*/ obinop(op, n->type); outi("movq %%rax, %%rcx\n"); popq("rax"); store(l->type); outi("movq %%rcx, %%rax\n"); }
static void incdec(Node *n) { if(!isitype(n->type) && !isptr(n->type)) panic("unimplemented incdec"); addr(n->Incdec.operand); pushq("rax"); load(n->type); if(isptr(n->type)) { if(n->Incdec.op == TOKINC) outi("add $%d, %%rax\n", n->type->Ptr.subty->size); else outi("add $%d, %%rax\n", -n->type->Ptr.subty->size); } else { if(n->Incdec.op == TOKINC) outi("inc %%rax\n"); else outi("dec %%rax\n"); } outi("movq %%rax, %%rcx\n"); popq("rax"); store(n->type); outi("movq %%rcx, %%rax\n"); if(n->Incdec.post == 1) { if(n->Incdec.op == TOKINC) outi("dec %%rax\n"); else outi("inc %%rax\n"); } }
static void call(Node *n) { int i, nargs, nintargs, cleanup; Vec *args; Node *arg; args = n->Call.args; i = nargs = args->len; /* Push args in reverse order */ while(i-- != 0) { arg = vecget(args, i); if(!isitype(arg->type) && !isptr(arg->type) && !isarray(arg->type) && !isfunc(arg->type)) errorposf(&arg->pos, "unimplemented arg type\n"); expr(arg); pushq("rax"); } nintargs = nargs; if(nintargs > 6) nintargs = 6; for(i = 0; i < nintargs; i++) popq(intargregs[i]); expr(n->Call.funclike); outi("call *%%rax\n"); cleanup = 8 * (nargs - nintargs); if(cleanup) { outi("add $%d, %%rsp\n", cleanup); stackoffset -= cleanup; } }
void emitsym(Sym *sym) { out("# emit sym %s\n", sym->name); switch(sym->k){ case SYMGLOBAL: if(sym->Global.sclass == SCEXTERN) break; if(isfunc(sym->type)) { func(sym->init, sym->Global.label, sym->Global.sclass == SCGLOBAL); break; } penddata(sym->Global.label, sym->type, sym->init, sym->Global.sclass == SCGLOBAL); break; case SYMLOCAL: if(sym->init) { expr(sym->init); pushq("rax"); outi("leaq %d(%%rbp), %%rax\n", sym->Local.slot->offset); popq("rcx"); if(!isptr(sym->type) && !isitype(sym->type) && !isstruct(sym->type)) errorf("unimplemented init\n"); store(sym->type); } break; case SYMENUM: case SYMTYPE: panic("internal error"); } out("\n"); }
void set_transition_callback(TransitionRule rule, int dur1, int dur2, TransitionCallback cb, void *arg) { static bool initialized = false; if(!rule) { return; } setq(rule, dur1, dur2, cb, arg); if(!initialized) { popq(); initialized = true; transition.rule2 = NULL; } if(transition.state == TRANS_IDLE || rule == transition.rule) { popq(); } }
void update_transition(void) { if(!check_transition()) { return; } if(transition.state == TRANS_FADE_IN) { transition.fade = approach(transition.fade, 1.0, 1.0/transition.dur1); if(transition.fade == 1.0) { transition.state = TRANS_FADE_OUT; call_callback(); if(popq()) { call_callback(); } } } else if(transition.state == TRANS_FADE_OUT) { transition.fade = transition.dur2 ? approach(transition.fade, 0.0, 1.0/transition.dur2) : 0.0; if(transition.fade == 0.0) { transition.state = TRANS_IDLE; popq(); } } }
static void addr(Node *n) { int sz; int offset; Sym *sym; switch(n->t) { case NUNOP: expr(n->Unop.operand); break; case NSEL: expr(n->Sel.operand); if(isptr(n->Sel.operand->type)) offset = structoffsetfromname(n->Sel.operand->type->Ptr.subty, n->Sel.name); else if(isstruct(n->Sel.operand->type)) offset = structoffsetfromname(n->Sel.operand->type, n->Sel.name); else panic("internal error"); if(offset < 0) panic("internal error"); outi("addq $%d, %%rax\n", offset); break; case NIDENT: sym = n->Ident.sym; switch(sym->k) { case SYMGLOBAL: outi("leaq %s(%%rip), %%rax\n", sym->Global.label); break; case SYMLOCAL: outi("leaq %d(%%rbp), %%rax\n", sym->Local.slot->offset); break; default: panic("internal error"); } break; case NIDX: expr(n->Idx.idx); sz = n->type->size; if(sz != 1) { outi("imul $%d, %%rax\n", sz); } pushq("rax"); expr(n->Idx.operand); popq("rcx"); outi("addq %%rcx, %%rax\n"); break; default: errorf("unimplemented addr\n"); } }
static void binop(Node *n) { if(n->Binop.op == TOKLAND || n->Binop.op == TOKLOR) { shortcircuit(n); return; } expr(n->Binop.l); pushq("rax"); expr(n->Binop.r); outi("movq %%rax, %%rcx\n"); popq("rax"); obinop(n->Binop.op, n->type); }
static void store(CTy *t) { if(isitype(t) || isptr(t)) { switch(t->size) { case 8: outi("movq %%rcx, (%%rax)\n"); break; case 4: outi("movl %%ecx, (%%rax)\n"); break; case 2: outi("movw %%cx, (%%rax)\n"); break; case 1: outi("movb %%cl, (%%rax)\n"); break; default: panic("internal error\n"); } return; } if(isstruct(t)) { pushq("rdi"); pushq("rsi"); pushq("rcx"); outi("movq %%rcx, %%rsi\n"); outi("movq %%rax, %%rdi\n"); outi("movq $%d, %%rcx\n", t->size); outi("rep movsb\n"); popq("rcx"); popq("rsi"); popq("rdi"); return; } errorf("unimplemented store\n"); }
static void vastart(Node *n) { int argend; expr(n->Builtin.Vastart.valist); /* XXX currently only support int args */ argend = (n->Builtin.Vastart.param->Ident.sym->Local.paramidx + 1) * 8; pushq("rcx"); outi("movl $%d, (%%rax)\n", argend); outi("movl $%d, 4(%%rax)\n", 48 + 0 * 16); outi("leaq %d(%%rbp), %%rcx\n", -176); outi("movq %%rcx, 16(%%rax)\n"); popq("rcx"); }
// void getPsrInfo(VM_Version::CpuidInfo* cpuid_info); address generate_getPsrInfo() { StubCodeMark mark(this, "VM_Version", "getPsrInfo_stub"); # define __ _masm-> address start = __ pc(); // rbx is callee-save on both unix and windows // rcx and rdx are first and second argument registers on windows __ pushq(rbx); __ movq(r8, rarg0); __ xorl(rax, rax); __ cpuid(); __ leaq(r9, Address(r8, in_bytes(VM_Version::std_cpuid0_offset()))); __ movl(Address(r9, 0), rax); __ movl(Address(r9, 4), rbx); __ movl(Address(r9, 8), rcx); __ movl(Address(r9, 12), rdx); __ movl(rax, 1); __ cpuid(); __ leaq(r9, Address(r8, in_bytes(VM_Version::std_cpuid1_offset()))); __ movl(Address(r9, 0), rax); __ movl(Address(r9, 4), rbx); __ movl(Address(r9, 8), rcx); __ movl(Address(r9, 12), rdx); __ movl(rax, 0x80000001); __ cpuid(); __ leaq(r9, Address(r8, in_bytes(VM_Version::ext_cpuid1_offset()))); __ movl(Address(r9, 0), rax); __ movl(Address(r9, 4), rbx); __ movl(Address(r9, 8), rcx); __ movl(Address(r9, 12), rdx); __ popq(rbx); __ ret(0); return start; }
void *master(void *arg){ int done = 0; //used for termination condition int c = 0; //put first piece of work in queue pthread_mutex_lock(&qlock); insert(0, listSize - 1); pthread_mutex_unlock(&qlock); while(done < numThreads - 1){ //check mailboxes and do work done = 0; for(c = 1; c < numThreads; c++){ pthread_mutex_lock(&lock[c]); if(mailbox[c].start == 0 && mailbox[c].end == -1){ //working //do nothing } else if(mailbox[c].start == -1 && mailbox[c].end == -1){ //waiting pthread_mutex_lock(&qlock); mailbox[c] = popq(); pthread_mutex_unlock(&qlock); } if(mailbox[c].start == -1 && mailbox[c].end == -1){ //no work available done++; } //otherwise mailbox should say done pthread_mutex_unlock(&lock[c]); } //end for } //end while //printf("done\n"); for(c = 1; c < numThreads; c++){ pthread_mutex_lock(&lock[c]); mailbox[c].start = -1; mailbox[c].end = 0; pthread_mutex_unlock(&lock[c]); } return NULL; }