void Assembler::movq(Immediate src, Indirect dest) { int64_t src_val = src.val; assert((-1L << 31) <= src_val && src_val < (1L << 31) - 1); int rex = REX_W; int dest_idx = dest.base.regnum; if (dest_idx >= 8) { rex |= REX_B; dest_idx -= 8; } emitRex(rex); emitByte(0xc7); bool needssib = (dest_idx == 0b100); int mode = getModeFromOffset(dest.offset); emitModRM(mode, 0, dest_idx); if (needssib) emitSIB(0b00, 0b100, dest_idx); if (mode == 0b01) { emitByte(dest.offset); } else if (mode == 0b10) { emitInt(dest.offset, 4); } emitInt(src_val, 4); }
void Assembler::cmp(Indirect mem, Immediate imm) { int64_t val = imm.val; assert((-1L << 31) <= val && val < (1L << 31) - 1); int src_idx = mem.base.regnum; int rex = REX_W; if (src_idx >= 8) { rex |= REX_B; src_idx -= 8; } assert(src_idx >= 0 && src_idx < 8); emitRex(rex); emitByte(0x81); if (mem.offset == 0) { emitModRM(0b00, 7, src_idx); } else if (-0x80 <= mem.offset && mem.offset < 0x80) { emitModRM(0b01, 7, src_idx); emitByte(mem.offset); } else { assert((-1L << 31) <= mem.offset && mem.offset < (1L << 31) - 1); emitModRM(0b10, 7, src_idx); emitInt(mem.offset, 4); } emitInt(val, 4); }
//----------------------------------------- int add(int left, int right) { emitInt("ld", left); emitInt("add", right); int temp = getTemp(); emitInstruction2("st", symbol[temp]); return temp; }
void checkSetLessThan() { int i, j; for (i = 0; i < lengthof(intValues); i++) { for (j = 0; j < lengthof(intValues); j++) { emitInt(_checkSetLessThanSigned(i, j)); emitInt(_checkSetLessThanUnsigned(i, j)); } } }
void Assembler::emitArith(Immediate imm, Register r, int opcode, MovType type) { // assert(r != RSP && "This breaks unwinding, please don't use."); int64_t amount = imm.val; RELEASE_ASSERT(fitsInto<int32_t>(amount), ""); assert(0 <= opcode && opcode < 8); assert(type == MovType::Q || type == MovType::L); int rex = type == MovType::Q ? REX_W : 0; int reg_idx = r.regnum; if (reg_idx >= 8) { rex |= REX_B; reg_idx -= 8; } if (rex) emitRex(rex); if (-0x80 <= amount && amount < 0x80) { emitByte(0x83); emitModRM(0b11, opcode, reg_idx); emitByte(amount); } else { emitByte(0x81); emitModRM(0b11, opcode, reg_idx); emitInt(amount, 4); } }
void Assembler::emitArith(Immediate imm, Register r, int opcode) { // assert(r != RSP && "This breaks unwinding, please don't use."); int64_t amount = imm.val; RELEASE_ASSERT((-1L << 31) <= amount && amount < (1L << 31) - 1, ""); assert(0 <= opcode && opcode < 8); int rex = REX_W; int reg_idx = r.regnum; if (reg_idx >= 8) { rex |= REX_B; reg_idx -= 8; } emitRex(rex); if (-0x80 <= amount && amount < 0x80) { emitByte(0x83); emitModRM(0b11, opcode, reg_idx); emitByte(amount); } else { emitByte(0x81); emitModRM(0b11, opcode, reg_idx); emitInt(amount, 4); } }
void Assembler::cmp(Indirect mem, Register reg) { int mem_idx = mem.base.regnum; int reg_idx = reg.regnum; int rex = REX_W; if (mem_idx >= 8) { rex |= REX_B; mem_idx -= 8; } if (reg_idx >= 8) { rex |= REX_R; reg_idx -= 8; } assert(mem_idx >= 0 && mem_idx < 8); assert(reg_idx >= 0 && reg_idx < 8); emitRex(rex); emitByte(0x3B); if (mem.offset == 0) { emitModRM(0b00, reg_idx, mem_idx); } else if (-0x80 <= mem.offset && mem.offset < 0x80) { emitModRM(0b01, reg_idx, mem_idx); emitByte(mem.offset); } else { assert((-1L << 31) <= mem.offset && mem.offset < (1L << 31) - 1); emitModRM(0b10, reg_idx, mem_idx); emitInt(mem.offset, 4); } }
void Assembler::jmp_cond(JumpDestination dest, ConditionCode condition) { bool unlikely = false; assert(dest.type == JumpDestination::FROM_START); int offset = dest.offset - (addr - start_addr) - 2; if (unlikely) offset--; if (offset >= -0x80 && offset < 0x80) { if (unlikely) emitByte(0x2e); emitByte(0x70 | condition); emitByte(offset); } else { offset -= 4; if (unlikely) emitByte(0x2e); emitByte(0x0f); emitByte(0x80 | condition); emitInt(offset, 4); } }
void Assembler::movsd(XMMRegister src, Indirect dest) { int rex = 0; int src_idx = src.regnum; int dest_idx = dest.base.regnum; if (src_idx >= 8) { rex |= REX_R; src_idx -= 8; } if (dest_idx >= 8) { trap(); rex |= REX_B; dest_idx -= 8; } emitByte(0xf2); if (rex) emitRex(rex); emitByte(0x0f); emitByte(0x11); bool needssib = (dest_idx == 0b100); int mode = getModeFromOffset(dest.offset); emitModRM(mode, src_idx, dest_idx); if (needssib) emitSIB(0b00, 0b100, dest_idx); if (mode == 0b01) { emitByte(dest.offset); } else if (mode == 0b10) { emitInt(dest.offset, 4); } }
//----------------------------------------- void println(int expVal) { emitInt("ld", expVal); emitInstruction1("dout"); emitInstruction1("ldc \'\\n\'"); emitInstruction1("aout"); }
void Assembler::mov(Register src, Indirect dest) { int rex = REX_W; int src_idx = src.regnum; int dest_idx = dest.base.regnum; assert(src_idx != dest_idx && "while valid this is almost certainly a register allocator bug"); if (src_idx >= 8) { rex |= REX_R; src_idx -= 8; } if (dest_idx >= 8) { rex |= REX_B; dest_idx -= 8; } emitRex(rex); emitByte(0x89); bool needssib = (dest_idx == 0b100); int mode = getModeFromOffset(dest.offset); emitModRM(mode, src_idx, dest_idx); if (needssib) emitSIB(0b00, 0b100, dest_idx); if (mode == 0b01) { emitByte(dest.offset); } else if (mode == 0b10) { emitInt(dest.offset, 4); } }
void Assembler::decq(Immediate imm) { emitByte(0x48); emitByte(0xff); emitByte(0x0c); emitByte(0x25); emitInt(imm.val, 4); }
void Assembler::lea(Indirect mem, Register reg) { int mem_idx = mem.base.regnum; int reg_idx = reg.regnum; int rex = REX_W; if (mem_idx >= 8) { rex |= REX_B; mem_idx -= 8; } if (reg_idx >= 8) { rex |= REX_R; reg_idx -= 8; } assert(mem_idx >= 0 && mem_idx < 8); assert(reg_idx >= 0 && reg_idx < 8); emitRex(rex); emitByte(0x8D); bool needssib = (mem_idx == 0b100); int mode = getModeFromOffset(mem.offset); emitModRM(mode, reg_idx, mem_idx); if (needssib) emitSIB(0b00, 0b100, mem_idx); if (mode == 0b01) { emitByte(mem.offset); } else if (mode == 0b10) { assert((-1L << 31) <= mem.offset && mem.offset < (1L << 31) - 1); emitInt(mem.offset, 4); } }
void Assembler::jmp(JumpDestination dest) { assert(dest.type == JumpDestination::FROM_START); int offset = dest.offset - (addr - start_addr) - 2; if (offset >= -0x80 && offset < 0x80) { emitByte(0xeb); emitByte(offset); } else { offset -= 3; emitByte(0xe9); emitInt(offset, 4); } }
void Assembler::cmp(Indirect mem, Immediate imm, MovType type) { int64_t val = imm.val; assert(fitsInto<int32_t>(val)); int src_idx = mem.base.regnum; assert(type == MovType::Q || type == MovType::L); int rex = type == MovType::Q ? REX_W : 0; if (src_idx >= 8) { rex |= REX_B; src_idx -= 8; } assert(src_idx >= 0 && src_idx < 8); bool needssib = (src_idx == 0b100); if (rex) emitRex(rex); emitByte(0x81); if (mem.offset == 0) { emitModRM(0b00, 7, src_idx); if (needssib) emitSIB(0b00, 0b100, src_idx); } else if (-0x80 <= mem.offset && mem.offset < 0x80) { emitModRM(0b01, 7, src_idx); if (needssib) emitSIB(0b00, 0b100, src_idx); emitByte(mem.offset); } else { assert(fitsInto<int32_t>(mem.offset)); emitModRM(0b10, 7, src_idx); if (needssib) emitSIB(0b00, 0b100, src_idx); emitInt(mem.offset, 4); } emitInt(val, 4); }
void Assembler::mov(Immediate val, Register dest) { int rex = REX_W; int dest_idx = dest.regnum; if (dest_idx >= 8) { rex |= REX_B; dest_idx -= 8; } emitRex(rex); emitByte(0xb8 + dest_idx); emitInt(val.val, 8); }
void Assembler::mov(Immediate val, Register dest, bool force_64bit_load) { force_64bit_load = force_64bit_load || !val.fitsInto32Bit(); int rex = force_64bit_load ? REX_W : 0; int dest_idx = dest.regnum; if (dest_idx >= 8) { rex |= REX_B; dest_idx -= 8; } if (rex) emitRex(rex); emitByte(0xb8 + dest_idx); emitInt(val.val, force_64bit_load ? 8 : 4); }
void Assembler::jmp(Indirect dest) { int reg_idx = dest.base.regnum; assert(reg_idx >= 0 && reg_idx < 8 && "not yet implemented"); emitByte(0xFF); if (dest.offset == 0) { emitModRM(0b00, 0b100, reg_idx); } else if (-0x80 <= dest.offset && dest.offset < 0x80) { emitModRM(0b01, 0b100, reg_idx); emitByte(dest.offset); } else { assert((-1L << 31) <= dest.offset && dest.offset < (1L << 31) - 1); emitModRM(0b10, 0b100, reg_idx); emitInt(dest.offset, 4); } }
void Assembler::cmp(Register reg, Immediate imm) { int64_t val = imm.val; assert((-1L << 31) <= val && val < (1L << 31) - 1); int reg_idx = reg.regnum; int rex = REX_W; if (reg_idx > 8) { rex |= REX_B; reg_idx -= 8; } assert(0 <= reg_idx && reg_idx < 8); emitRex(rex); emitByte(0x81); emitModRM(0b11, 7, reg_idx); emitInt(val, 4); }
void Assembler::movsd(Indirect src, XMMRegister dest) { int rex = 0; int src_idx = src.base.regnum; int dest_idx = dest.regnum; if (src_idx >= 8) { trap(); rex |= REX_R; src_idx -= 8; } if (dest_idx >= 8) { trap(); rex |= REX_B; dest_idx -= 8; } emitByte(0xf2); if (rex) emitRex(rex); emitByte(0x0f); emitByte(0x10); bool needssib = (src_idx == 0b100); int mode; if (src.offset == 0) mode = 0b00; else if (-0x80 <= src.offset && src.offset < 0x80) mode = 0b01; else mode = 0b10; emitModRM(mode, dest_idx, src_idx); if (needssib) emitSIB(0b00, 0b100, src_idx); if (mode == 0b01) { emitByte(src.offset); } else if (mode == 0b10) { emitInt(src.offset, 4); } }
void Assembler::emitArith(Immediate imm, Indirect mem, int opcode) { int64_t amount = imm.val; assert(fitsInto<int32_t>(amount)); assert(0 <= opcode && opcode < 8); int rex = REX_W; int mem_idx = mem.base.regnum; if (mem_idx >= 8) { rex |= REX_B; mem_idx -= 8; } emitRex(rex); bool needssib = (mem_idx == 0b100); assert(!needssib && "untested"); int mode = getModeFromOffset(mem.offset, mem_idx); assert(mode != 0b10 && "not yet supported"); if (-0x80 <= amount && amount < 0x80) { emitByte(0x83); if (needssib) emitSIB(0b00, 0b100, mem_idx); emitModRM(mode, opcode, mem_idx); if (mode == 0b01) emitByte(mem.offset); emitByte(amount); } else { emitByte(0x81); if (needssib) emitSIB(0b00, 0b100, mem_idx); emitModRM(mode, opcode, mem_idx); if (mode == 0b01) emitByte(mem.offset); emitInt(amount, 4); } }
/* edge attributes: * label * graphics * LabelGraphics */ static void emitEdgeAttrs (Agraph_t* G, Agedge_t* ep, FILE* outFile, int ix) { Agsym_t* s; char* v; edge_attrs attrs; int doGraphics = 0; int doLabelGraphics = 0; char* label = 0; int style; /* First, process the attributes, saving the graphics attributes */ memset(&attrs,0, sizeof(attrs)); for (s = agnxtattr (G, AGEDGE, NULL); s; s = agnxtattr (G, AGEDGE, s)) { if (streq(s->name, "style")) { /* hasFill outlineStyle invis */ if (*(v = agxget (ep, s))) { style = parseStyle (v); if (style & INVIS) attrs.flags |= INVIS; if (style & LINE) attrs.flags |= LINE; if (style & DASH) attrs.flags |= DASH; if (style & DOT) attrs.flags |= DOT; if (style & BOLD) attrs.width = "2"; doGraphics = 1; } } else if (streq(s->name, "label")) { if (*(v = agxget (ep, s))) { label = v; emitAttr (s->name, label, outFile, ix); doLabelGraphics = 1; } } else if (streq(s->name, "penwidth")) { if (*(v = agxget (ep, s))) { attrs.width = v; doGraphics = 1; } } else if (streq(s->name, "pos")) { if (*(v = agxget (ep, s))) { doGraphics = 1; attrs.pos = v; } } else if (streq(s->name, "dir")) { if (*(v = agxget (ep, s))) { doGraphics = 1; attrs.arrow = v; } } else if (streq(s->name, "color")) { if (*(v = agxget (ep, s))) { attrs.fill = v; doGraphics = 1; } } else if (streq(s->name, "pencolor")) { if (*(v = agxget (ep, s))) { attrs.fill = v; doGraphics = 1; } } else if (streq(s->name, "arrowhead")) { if (*(v = agxget (ep, s))) { attrs.arrowhead = v; doGraphics = 1; } } else if (streq(s->name, "arrowtail")) { if (*(v = agxget (ep, s))) { attrs.arrowtail = v; doGraphics = 1; } } else if (streq(s->name, "fontname")) { /* fontName */ if (*(v = agxget (ep, s))) { attrs.fontName = v; doLabelGraphics = 1; } } else if (streq(s->name, "fontsize")) { /* fontSize */ if (*(v = agxget (ep, s))) { attrs.fontSize = v; doLabelGraphics = 1; } } else if (streq(s->name, "fontcolor")) { /* fontColor */ if (*(v = agxget (ep, s))) { attrs.fontColor = v; doLabelGraphics = 1; } } else { v = agxget (ep, s); emitAttr (s->name, v, outFile, ix); } } /* Then, print them, if any */ if (doGraphics) { fprintf (outFile, " graphics [\n"); if (attrs.pos) { emitSpline (attrs.pos, outFile, ix+1); } if (attrs.flags & INVIS) { emitInt ("visible", 0, outFile, ix+1); } if (attrs.fill) { emitAttr ("fill", attrs.fill, outFile, ix+1); } if (attrs.width) { emitAttr ("width", attrs.width, outFile, ix+1); } if (attrs.arrowhead) { emitAttr ("targetArrow", attrs.arrowhead, outFile, ix+1); } if (attrs.arrowtail) { emitAttr ("sourceArrow", attrs.arrowtail, outFile, ix+1); } if (attrs.flags & DASH) { emitAttr ("style", "dashed", outFile, ix+1); } else if (attrs.flags & DOT) { emitAttr ("style", "dotted", outFile, ix+1); } else if (attrs.flags & LINE) { emitAttr ("style", "line", outFile, ix+1); } if (attrs.arrow) { if (streq(attrs.arrow,"forward")) emitAttr ("arrow", "first", outFile, ix+1); else if (streq(attrs.arrow,"back")) emitAttr ("arrow", "last", outFile, ix+1); else if (streq(attrs.arrow,"both")) emitAttr ("arrow", "both", outFile, ix+1); else if (streq(attrs.arrow,"none")) emitAttr ("arrow", "none", outFile, ix+1); } fprintf (outFile, " ]\n"); } if (doLabelGraphics) { fprintf (outFile, " LabelGraphics [\n"); if (label) emitAttr ("text", label, outFile, ix+1); if (attrs.fontColor) { emitAttr ("fontColor", attrs.fontColor, outFile, ix+1); } if (attrs.fontSize) { emitAttr ("fontSize", attrs.fontSize, outFile, ix+1); } if (attrs.fontName) { emitAttr ("fontName", attrs.fontName, outFile, ix+1); } fprintf (outFile, " ]\n"); } }
int main(int argc, char **argv) { emitInt(argc > 0); emitInt(strlen(argv[0]) > 0); return 0; }
/* node attributes: * label * graphics * LabelGraphics */ static void emitNodeAttrs (Agraph_t* G, Agnode_t* np, FILE* outFile, int ix) { Agsym_t* s; char* v; node_attrs attrs; int doGraphics = 0; int doLabelGraphics = 0; char* label = 0; int style; double x, y; /* First, process the attributes, saving the graphics attributes */ memset(&attrs,0, sizeof(attrs)); for (s = agnxtattr (G, AGNODE, NULL); s; s = agnxtattr (G, AGNODE, s)) { if (streq(s->name, "style")) { /* hasFill outlineStyle invis */ if (*(v = agxget (np, s))) { style = parseStyle (v); if (style & INVIS) attrs.flags |= INVIS; if (style & FILL) attrs.flags |= FILL; if (style & LINE) attrs.outlineStyle = "line"; if (style & DASH) attrs.outlineStyle = "dashed"; if (style & DOT) attrs.outlineStyle = "dotted"; doGraphics = 1; } } else if (streq(s->name, "label")) { v = agxget (np, s); if (streq("\\N", v)) { label = agnameof(np); emitAttr (s->name, label, outFile, ix); doLabelGraphics = 1; } else if (*v) { label = v; emitAttr (s->name, label, outFile, ix); doLabelGraphics = 1; } } else if (streq(s->name, "penwidth")) { if (*(v = agxget (np, s))) { attrs.width = v; doGraphics = 1; } } else if (streq(s->name, "width")) { v = agxget (np, s); if (*v) { attrs.w = 72.0*atof (v); attrs.flags |= W_SET; doGraphics = 1; } } else if (streq(s->name, "height")) { v = agxget (np, s); if (*v) { attrs.h = 72.0*atof (v); attrs.flags |= H_SET; doGraphics = 1; } } else if (streq(s->name, "pos")) { v = agxget (np, s); if (sscanf (v, "%lf,%lf", &x, &y) == 2) { doGraphics = 1; attrs.x = x; attrs.y = y; attrs.flags |= POS_SET; } } else if (streq(s->name, "shape")) { /* type */ if (*(v = agxget (np, s))) { attrs.type = v; doGraphics = 1; } } else if (streq(s->name, "color")) { if (*(v = agxget (np, s))) { attrs.fill = v; attrs.outline = v; doGraphics = 1; } } else if (streq(s->name, "fillcolor")) { if (*(v = agxget (np, s))) { attrs.fill = v; doGraphics = 1; } } else if (streq(s->name, "pencolor")) { if (*(v = agxget (np, s))) { attrs.outline = v; doGraphics = 1; } } else if (streq(s->name, "fontname")) { /* fontName */ if (*(v = agxget (np, s))) { attrs.fontName = v; doLabelGraphics = 1; } } else if (streq(s->name, "fontsize")) { /* fontSize */ if (*(v = agxget (np, s))) { attrs.fontSize = v; doLabelGraphics = 1; } } else if (streq(s->name, "fontcolor")) { /* fontColor */ if (*(v = agxget (np, s))) { attrs.fontColor = v; doLabelGraphics = 1; } } else { v = agxget (np, s); emitAttr (s->name, v, outFile, ix); } } /* Then, print them, if any */ if (doGraphics) { fprintf (outFile, " graphics [\n"); if (attrs.flags & POS_SET) { emitReal ("x", attrs.x, outFile, ix+1); emitReal ("y", attrs.y, outFile, ix+1); } if (attrs.flags & W_SET) { emitReal ("w", attrs.w, outFile, ix+1); } if (attrs.flags & H_SET) { emitReal ("H", attrs.h, outFile, ix+1); } if (attrs.flags & INVIS) { emitInt ("visible", 0, outFile, ix+1); } if (attrs.flags & FILL) { emitInt ("hasFill", 1, outFile, ix+1); } if (attrs.type) { emitAttr ("type", attrs.type, outFile, ix+1); } if (attrs.image) { emitAttr ("image", attrs.image, outFile, ix+1); } if (attrs.fill) { emitAttr ("fill", attrs.fill, outFile, ix+1); } if (attrs.outline) { emitAttr ("outline", attrs.outline, outFile, ix+1); } if (attrs.width) { emitAttr ("width", attrs.width, outFile, ix+1); } if (attrs.outlineStyle) { emitAttr ("outlineStyle", attrs.outlineStyle, outFile, ix+1); } fprintf (outFile, " ]\n"); } if (doLabelGraphics) { fprintf (outFile, " LabelGraphics [\n"); if (label) emitAttr ("text", label, outFile, ix+1); if (attrs.fontColor) { emitAttr ("fontColor", attrs.fontColor, outFile, ix+1); } if (attrs.fontSize) { emitAttr ("fontSize", attrs.fontSize, outFile, ix+1); } if (attrs.fontName) { emitAttr ("fontName", attrs.fontName, outFile, ix+1); } fprintf (outFile, " ]\n"); } }
//----------------------------------------- void assign(int left, int expVal) { emitInt("ld", expVal); emitInt("st", left); }
void Assembler::mov_generic(Indirect src, Register dest, MovType type) { int rex; switch (type) { case MovType::Q: case MovType::ZBQ: case MovType::SBQ: case MovType::ZWQ: case MovType::SWQ: case MovType::SLQ: rex = REX_W; break; case MovType::L: case MovType::B: case MovType::ZBL: case MovType::SBL: case MovType::ZWL: case MovType::SWL: rex = 0; break; default: RELEASE_ASSERT(false, "unrecognized MovType"); } int src_idx = src.base.regnum; int dest_idx = dest.regnum; if (src_idx >= 8) { rex |= REX_B; src_idx -= 8; } if (dest_idx >= 8) { rex |= REX_R; dest_idx -= 8; } if (rex) emitRex(rex); // opcode switch (type) { case MovType::Q: case MovType::L: emitByte(0x8b); break; case MovType::B: emitByte(0x8a); break; case MovType::ZBQ: case MovType::ZBL: emitByte(0x0f); emitByte(0xb6); break; case MovType::SBQ: case MovType::SBL: emitByte(0x0f); emitByte(0xbe); break; case MovType::ZWQ: case MovType::ZWL: emitByte(0x0f); emitByte(0xb7); break; case MovType::SWQ: case MovType::SWL: emitByte(0x0f); emitByte(0xbf); break; case MovType::SLQ: emitByte(0x63); break; default: RELEASE_ASSERT(false, "unrecognized MovType"); } bool needssib = (src_idx == 0b100); int mode; if (src.offset == 0) mode = 0b00; else if (-0x80 <= src.offset && src.offset < 0x80) mode = 0b01; else mode = 0b10; emitModRM(mode, dest_idx, src_idx); if (needssib) emitSIB(0b00, 0b100, src_idx); if (mode == 0b01) { emitByte(src.offset); } else if (mode == 0b10) { emitInt(src.offset, 4); } }
void Assembler::incl(Immediate imm) { emitByte(0xff); emitByte(0x04); emitByte(0x25); emitInt(imm.val, 4); }
void Assembler::call(Immediate imm) { emitByte(0xe8); emitInt(imm.val, 4); }
void test() { int v = 1; v += v * GlobalValue1; v += v * GlobalValue2; emitInt(v); }
EmitCInlines(AstNetlist* nodep) { nodep->accept(*this); if (v3Global.needHInlines()) { emitInt(); } }