/* * i386 specific functions for TCC assembler * * Copyright (c) 2001, 2002 Fabrice Bellard * Copyright (c) 2009 Frédéric Feret (x86_64 support) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "tcc.h" #define MAX_OPERANDS 3 #define TOK_ASM_first TOK_ASM_clc #define TOK_ASM_last TOK_ASM_emms #define TOK_ASM_alllast TOK_ASM_subps #define OPC_B 0x01 /* only used with OPC_WL */ #define OPC_WL 0x02 /* accepts w, l or no suffix */ #define OPC_BWL (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */ #define OPC_REG 0x04 /* register is added to opcode */ #define OPC_MODRM 0x08 /* modrm encoding */ #define OPCT_MASK 0x70 #define OPC_FWAIT 0x10 /* add fwait opcode */ #define OPC_SHIFT 0x20 /* shift opcodes */ #define OPC_ARITH 0x30 /* arithmetic opcodes */ #define OPC_FARITH 0x40 /* FPU arithmetic opcodes */ #define OPC_TEST 0x50 /* test opcodes */ #define OPCT_IS(v,i) (((v) & OPCT_MASK) == (i)) #define OPC_0F 0x100 /* Is secondary map (0x0f prefix) */ #define OPC_48 0x200 /* Always has REX prefix */ #ifdef TCC_TARGET_X86_64 # define OPC_WLQ 0x1000 /* accepts w, l, q or no suffix */ # define OPC_BWLQ (OPC_B | OPC_WLQ) /* accepts b, w, l, q or no suffix */ # define OPC_WLX OPC_WLQ # define OPC_BWLX OPC_BWLQ #else # define OPC_WLX OPC_WL # define OPC_BWLX OPC_BWL #endif #define OPC_GROUP_SHIFT 13 /* in order to compress the operand type, we use specific operands and we or only with EA */ enum { OPT_REG8=0, /* warning: value is hardcoded from TOK_ASM_xxx */ OPT_REG16, /* warning: value is hardcoded from TOK_ASM_xxx */ OPT_REG32, /* warning: value is hardcoded from TOK_ASM_xxx */ #ifdef TCC_TARGET_X86_64 OPT_REG64, /* warning: value is hardcoded from TOK_ASM_xxx */ #endif OPT_MMX, /* warning: value is hardcoded from TOK_ASM_xxx */ OPT_SSE, /* warning: value is hardcoded from TOK_ASM_xxx */ OPT_CR, /* warning: value is hardcoded from TOK_ASM_xxx */ OPT_TR, /* warning: value is hardcoded from TOK_ASM_xxx */ OPT_DB, /* warning: value is hardcoded from TOK_ASM_xxx */ OPT_SEG, OPT_ST, #ifdef TCC_TARGET_X86_64 OPT_REG8_LOW, /* %spl,%bpl,%sil,%dil, encoded like ah,ch,dh,bh, but with REX prefix, not used in insn templates */ #endif OPT_IM8, OPT_IM8S, OPT_IM16, OPT_IM32, #ifdef TCC_TARGET_X86_64 OPT_IM64, #endif OPT_EAX, /* %al, %ax, %eax or %rax register */ OPT_ST0, /* %st(0) register */ OPT_CL, /* %cl register */ OPT_DX, /* %dx register */ OPT_ADDR, /* OP_EA with only offset */ OPT_INDIR, /* *(expr) */ /* composite types */ OPT_COMPOSITE_FIRST, OPT_IM, /* IM8 | IM16 | IM32 */ OPT_REG, /* REG8 | REG16 | REG32 | REG64 */ OPT_REGW, /* REG16 | REG32 | REG64 */ OPT_IMW, /* IM16 | IM32 */ OPT_MMXSSE, /* MMX | SSE */ OPT_DISP, /* Like OPT_ADDR, but emitted as displacement (for jumps) */ OPT_DISP8, /* Like OPT_ADDR, but only 8bit (short jumps) */ /* can be ored with any OPT_xxx */ OPT_EA = 0x80 }; #define OP_REG8 (1 << OPT_REG8) #define OP_REG16 (1 << OPT_REG16) #define OP_REG32 (1 << OPT_REG32) #define OP_MMX (1 << OPT_MMX) #define OP_SSE (1 << OPT_SSE) #define OP_CR (1 << OPT_CR) #define OP_TR (1 << OPT_TR) #define OP_DB (1 << OPT_DB) #define OP_SEG (1 << OPT_SEG) #define OP_ST (1 << OPT_ST) #define OP_IM8 (1 << OPT_IM8) #define OP_IM8S (1 << OPT_IM8S) #define OP_IM16 (1 << OPT_IM16) #define OP_IM32 (1 << OPT_IM32) #define OP_EAX (1 << OPT_EAX) #define OP_ST0 (1 << OPT_ST0) #define OP_CL (1 << OPT_CL) #define OP_DX (1 << OPT_DX) #define OP_ADDR (1 << OPT_ADDR) #define OP_INDIR (1 << OPT_INDIR) #ifdef TCC_TARGET_X86_64 # define OP_REG64 (1 << OPT_REG64) # define OP_REG8_LOW (1 << OPT_REG8_LOW) # define OP_IM64 (1 << OPT_IM64) # define OP_EA32 (OP_EA << 1) #else # define OP_REG64 0 # define OP_REG8_LOW 0 # define OP_IM64 0 # define OP_EA32 0 #endif #define OP_EA 0x40000000 #define OP_REG (OP_REG8 | OP_REG16 | OP_REG32 | OP_REG64) #ifdef TCC_TARGET_X86_64 # define TREG_XAX TREG_RAX # define TREG_XCX TREG_RCX # define TREG_XDX TREG_RDX #else # define TREG_XAX TREG_EAX # define TREG_XCX TREG_ECX # define TREG_XDX TREG_EDX #endif typedef struct ASMInstr { uint16_t sym; uint16_t opcode; uint16_t instr_type; uint8_t nb_ops; uint8_t op_type[MAX_OPERANDS]; /* see OP_xxx */ } ASMInstr; typedef struct Operand { uint32_t typ
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
enum { Tfnord, Tdev, Tnet, Twork, Tmisc, TLast };
#define ARRANGE dotile /* dofloat */
#define DEFTAG Tdev
#define FONT "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*"
#define BGCOLOR "#0a2c2d"
#define FGCOLOR "#ddeeee"
#define BORDERCOLOR "#176164"
#define MODKEY Mod1Mask
#define NUMLOCKMASK Mod2Mask
#define MASTERW 52 /* percent */
#define TAGS \
char *tags[TLast] = { \
[Tfnord] = "fnord", \
[Tdev] = "dev", \
[Tnet] = "net", \
[Twork] = "work", \
[Tmisc] = "misc", \
};
#define KEYS \
const char *browse[] = { "firefox", NULL }; \
const char *gimp[] = { "gimp", NULL }; \
const char *term[] = { \
"urxvt", "-tr", "+sb", "-bg", "black", "-fg", "white", "-cr", "white", \
"-fn", "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*", NULL \
}; \
const char *xlock[] = { "xlock", NULL }; \
static Key key[] = { \
/* modifier key function arguments */ \
{ MODKEY, XK_0, view, { .i = Tfnord } }, \
{ MODKEY, XK_1, view, { .i = Tdev } }, \
{ MODKEY, XK_2, view, { .i = Tnet } }, \
{ MODKEY, XK_3, view, { .i = Twork } }, \
{ MODKEY, XK_4, view, { .i = Tmisc} }, \
{ MODKEY, XK_h, viewprev, { 0 } }, \
{ MODKEY, XK_j, focusnext, { 0 } }, \
{ MODKEY, XK_k, focusprev, { 0 } }, \
{ MODKEY, XK_l, viewnext, { 0 } }, \
{ MODKEY, XK_m, togglemax, { 0 } }, \
{ MODKEY, XK_space, togglemode, { 0 } }, \
{ MODKEY, XK_Return, zoom, { 0 } }, \
{ MODKEY|ControlMask, XK_0, appendtag, { .i = Tfnord } }, \
{ MODKEY|ControlMask, XK_1, appendtag, { .i = Tdev } }, \
{ MODKEY|ControlMask, XK_2, appendtag, { .i = Tnet } }, \
{ MODKEY|ControlMask, XK_3, appendtag, { .i = Twork } }, \
{ MODKEY|ControlMask, XK_4, appendtag, { .i = Tmisc } }, \
{ MODKEY|ShiftMask, XK_0, replacetag, { .i = Tfnord } }, \
{ MODKEY|ShiftMask, XK_1, replacetag, { .i = Tdev } }, \
{ MODKEY|ShiftMask, XK_2, replacetag, { .i = Tnet } }, \
{ MODKEY|ShiftMask, XK_3, replacetag, { .i = Twork } }, \
{ MODKEY|ShiftMask, XK_4, replacetag, { .i = Tmisc } }, \
{ MODKEY|ShiftMask, XK_c, killclient, { 0 } }, \
{ MODKEY|ShiftMask, XK_q, quit, { 0 } }, \
{ MODKEY|ShiftMask, XK_Return, spawn, { .argv = term } }, \
{ MODKEY|ShiftMask, XK_g, spawn, { .argv = gimp } }, \
{ MODKEY|ShiftMask, XK_l, spawn, { .argv = xlock } }, \
{ MODKEY|ShiftMask, XK_w, spawn, { .argv = browse } }, \
};
#define RULES \
static Rule rule[] = { \
/* class:instance tags isfloat */ \
{ "Firefox.*", { [Tnet] = "net" }, False }, \
{ "Gimp.*", { 0 }, True}, \
};