public inbox for b43-dev@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH] b43-asm: Add 3 new virtual instructions.
@ 2011-11-12 17:31 francesco.gringoli at ing.unibs.it
  2011-11-12 18:05 ` Michael Büsch
  0 siblings, 1 reply; 6+ messages in thread
From: francesco.gringoli at ing.unibs.it @ 2011-11-12 17:31 UTC (permalink / raw)
  To: b43-dev

Hi Michael,

I added three new (virtual) instructions to make the code more readable.
These are "human-friendly" versions of orx, jzx and jnzx, e.g., one can
use "orxh" like

	orxh	(r1 << 8) & 0x0100, r2 & ~0x0100, r2

instead of

	orx	0, 8, r1, r2, r2

or better write

#define	NEED_ACK	0x10
#define	NEED_BEACON	0x20
	orxh	NEED_ACK, r1 & ~(NEED_ACK|NEED_BEACON), r2

instead of

	orx	1, 4, 0x1, r1, r2

Similarly:

	jzxh	(r12 << 16 | r13) & 0x1F000, label

instead of

	jzx	4, 12, r13, r12, label

Examples added to test.asm and README.

Regards,
-Francesco

-------------=--------------
The following changes are made to b43-tools

1) b43-asm assembles new virtual instructions orxh, jzxh, jnzxh

Signed-off-by: Francesco Gringoli <francesco.gringoli@ing.unibs.it>

Index: b43-tools/assembler/main.c
===================================================================
--- b43-tools/assembler/main.c	2011-09-12 16:47:26.000000000 +0200
+++ b43-tools/assembler/main.c	2011-11-12 13:39:05.000000000 +0100
@@ -503,6 +503,106 @@
 	do_assemble_insn(ctx, insn, opcode);
 }
 
+static unsigned int merge_ext_into_opcode_human(struct assembler_context *ctx,
+						unsigned int opbase,
+						struct instruction *insn)
+{
+	struct operlist *ol;
+	unsigned int opcode;
+
+	unsigned long masks[256];
+	unsigned long m, s, j = 0;
+	unsigned long imm, shift, mask, mask2;
+	for(m = 0; m < 16; m++) {
+		mask = (1 << (m+1)) - 1;
+		for(s = 0; s < 16; s++) {
+			mask2 = (mask << s) | (mask >> (16 - s));
+			mask2 = mask2 & 0xFFFF;
+			masks[j] = mask2;
+			j++;
+		}
+	}
+
+	opcode = opbase;
+	ol = insn->operands;
+
+	for(j = 0; j < 256; j++)
+		if(masks[j] == ((~ol->oper[5]->u.raw) & 0xFFFF))
+			break;
+	if(j == 256)
+		asm_error(ctx, "can't build valid mask");
+	m = j / 16; s = j % 16;
+	mask = (1 << (m + 1)) - 1;
+	mask = (mask << s) | (mask >> (16 - s));
+	if(mask != ((~ol->oper[5]->u.raw) & 0xFFFF))
+		asm_error(ctx, "can't match mask");
+
+	if(ol->oper[4]->u.raw != 0)
+		asm_error(ctx, "can't use shift here");
+
+	shift = ol->oper[1]->u.raw;
+	mask = ol->oper[2]->u.raw;
+
+	if(ol->oper[0]->type == OPER_IMM) {
+		imm = ((ol->oper[0]->u.imm->imm << shift) & mask) & 0xFFFF;
+		ol->oper[0]->u.imm->imm = imm;
+		imm = ((imm >> s) | (imm << (16-s))) & 0xFFFF;
+		if(imm & ~0x3FF ||
+		   ol->oper[0]->u.imm->imm != (((imm << s) | (imm >> (16-s))) & 0xFFFF))
+			asm_error(ctx, "immediate value can't be encoded");
+		ol->oper[0]->u.imm->imm = imm;
+	} else {
+		if(shift > 15)
+			asm_error(ctx, "invalid shift");
+		if(mask != ((~ol->oper[5]->u.raw) & 0xFFFF))
+			asm_error(ctx, "unmatched masks");
+	}
+
+	opcode |= (m << 4);
+	opcode |= s;
+
+	ol->oper[1] = ol->oper[3];
+	ol->oper[2] = ol->oper[6];
+
+	return opcode;
+}
+
+static unsigned int merge_ext_into_opcode_human2(struct assembler_context *ctx,
+						 unsigned int opbase,
+						 struct instruction *insn)
+{
+	struct operlist *ol;
+	unsigned long masks[256];
+	unsigned long m, s, j = 0;
+	unsigned long mask;
+	unsigned int opcode = opbase;
+	for(m = 0; m < 16; m++) {
+		mask = (1 << (m+1)) - 1;
+		for(s = 0; s < 16; s++) {
+			masks[j] = (mask << s) & 0xFFFFFFFF;
+			j++;
+		}
+	}
+
+	ol = insn->operands;
+
+	for(j = 0; j < 256; j++)
+		if(ol->oper[2]->u.imm->imm == masks[j])
+			break;
+	if(j == 256)
+		asm_error(ctx, "can't build valid mask");
+	m = j / 16; s = j % 16;
+	mask = (1 << (m + 1)) - 1;
+	mask = (mask << s) & 0xFFFFFFFF;
+	if(mask != ol->oper[2]->u.imm->imm)
+		asm_error(ctx, "can't match mask");
+	opcode |= (m << 4);
+	opcode |= s;
+
+	ol->oper[2] = ol->oper[3];
+	return opcode;
+}
+
 static unsigned int merge_ext_into_opcode(struct assembler_context *ctx,
 					  unsigned int opbase,
 					  struct instruction *insn)
@@ -799,6 +899,10 @@
 		opcode = merge_ext_into_opcode(ctx, 0x300, insn);
 		do_assemble_insn(ctx, insn, opcode);
 		break;
+	case OP_ORXH:
+		opcode = merge_ext_into_opcode_human(ctx, 0x300, insn);
+		do_assemble_insn(ctx, insn, opcode);
+		break;
 	case OP_MOV:
 		emulate_mov_insn(ctx, insn);
 		return;
@@ -879,11 +983,21 @@
 		out = do_assemble_insn(ctx, insn, opcode);
 		out->is_jump_insn = 1;
 		break;
+	case OP_JZXH:
+		opcode = merge_ext_into_opcode_human2(ctx, 0x400, insn);
+		out = do_assemble_insn(ctx, insn, opcode);
+		out->is_jump_insn = 1;
+		break;
 	case OP_JNZX:
 		opcode = merge_ext_into_opcode(ctx, 0x500, insn);
 		out = do_assemble_insn(ctx, insn, opcode);
 		out->is_jump_insn = 1;
 		break;
+	case OP_JNZXH:
+		opcode = merge_ext_into_opcode_human2(ctx, 0x500, insn);
+		out = do_assemble_insn(ctx, insn, opcode);
+		out->is_jump_insn = 1;
+		break;
 	case OP_JEXT:
 		opcode = merge_external_jmp_into_opcode(ctx, 0x700, insn);
 		out = do_assemble_insn(ctx, insn, opcode);
Index: b43-tools/assembler/main.h
===================================================================
--- b43-tools/assembler/main.h	2011-09-11 19:59:43.000000000 +0200
+++ b43-tools/assembler/main.h	2011-11-10 11:26:46.000000000 +0100
@@ -96,8 +96,14 @@
 	} u;
 };
 
+struct operand_shift_mask {
+	struct operand *op;
+	unsigned int mask;
+	unsigned int shift;
+};
+
 struct operlist {
-	struct operand *oper[5];
+	struct operand *oper[7];
 };
 
 struct instruction {
Index: b43-tools/assembler/parser.y
===================================================================
--- b43-tools/assembler/parser.y	2011-09-12 16:57:33.000000000 +0200
+++ b43-tools/assembler/parser.y	2011-11-12 16:41:41.000000000 +0100
@@ -43,7 +43,7 @@
 
 %token EQUAL NOT_EQUAL LOGICAL_OR LOGICAL_AND PLUS MINUS MULTIPLY DIVIDE BITW_OR BITW_AND BITW_XOR BITW_NOT LEFTSHIFT RIGHTSHIFT
 
-%token OP_MUL OP_ADD OP_ADDSC OP_ADDC OP_ADDSCC OP_SUB OP_SUBSC OP_SUBC OP_SUBSCC OP_SRA OP_OR OP_AND OP_XOR OP_SR OP_SRX OP_SL OP_RL OP_RR OP_NAND OP_ORX OP_MOV OP_JMP OP_JAND OP_JNAND OP_JS OP_JNS OP_JE OP_JNE OP_JLS OP_JGES OP_JGS OP_JLES OP_JL OP_JGE OP_JG OP_JLE OP_JZX OP_JNZX OP_JEXT OP_JNEXT OP_JDN OP_JDPZ OP_JDP OP_JDNZ OP_CALL OP_CALLS OP_RET OP_RETS OP_TKIPH OP_TKIPHS OP_TKIPL OP_TKIPLS OP_NAP RAW_CODE
+%token OP_MUL OP_ADD OP_ADDSC OP_ADDC OP_ADDSCC OP_SUB OP_SUBSC OP_SUBC OP_SUBSCC OP_SRA OP_OR OP_AND OP_XOR OP_SR OP_SRX OP_SL OP_RL OP_RR OP_NAND OP_ORX OP_ORXH OP_MOV OP_JMP OP_JAND OP_JNAND OP_JS OP_JNS OP_JE OP_JNE OP_JLS OP_JGES OP_JGS OP_JLES OP_JL OP_JGE OP_JG OP_JLE OP_JZX OP_JZXH OP_JNZX OP_JNZXH OP_JEXT OP_JNEXT OP_JDN OP_JDPZ OP_JDP OP_JDNZ OP_CALL OP_CALLS OP_RET OP_RETS OP_TKIPH OP_TKIPHS OP_TKIPL OP_TKIPLS OP_NAP RAW_CODE
 
 %token IVAL_MMIO16 IVAL_MMIO32 IVAL_PHY IVAL_RADIO IVAL_SHM16 IVAL_SHM32 IVAL_TRAM
 
@@ -316,6 +316,13 @@
 			s->u.insn = $1;
 			$$ = s;
 		  }
+		| insn_orxh {
+			struct statement *s = xmalloc(sizeof(struct statement));
+			INIT_LIST_HEAD(&s->list);
+			s->type = STMT_INSN;
+			s->u.insn = $1;
+			$$ = s;
+		}
 		| insn_mov {
 			struct statement *s = xmalloc(sizeof(struct statement));
 			INIT_LIST_HEAD(&s->list);
@@ -463,6 +470,13 @@
 			s->u.insn = $1;
 			$$ = s;
 		  }
+		| insn_jzxh {
+			struct statement *s = xmalloc(sizeof(struct statement));
+			INIT_LIST_HEAD(&s->list);
+			s->type = STMT_INSN;
+			s->u.insn = $1;
+			$$ = s;
+		  }
 		| insn_jnzx {
 			struct statement *s = xmalloc(sizeof(struct statement));
 			INIT_LIST_HEAD(&s->list);
@@ -470,6 +484,13 @@
 			s->u.insn = $1;
 			$$ = s;
 		  }
+		| insn_jnzxh {
+			struct statement *s = xmalloc(sizeof(struct statement));
+			INIT_LIST_HEAD(&s->list);
+			s->type = STMT_INSN;
+			s->u.insn = $1;
+			$$ = s;
+		  }
 		| insn_jext {
 			struct statement *s = xmalloc(sizeof(struct statement));
 			INIT_LIST_HEAD(&s->list);
@@ -795,6 +816,14 @@
 		  }
 		;
 
+insn_orxh	: OP_ORXH operlist_3_human {
+			struct instruction *insn = xmalloc(sizeof(struct instruction));
+			insn->op = OP_ORXH;
+			insn->operands = $2;
+			$$ = insn;
+		  }
+		;
+
 insn_mov	: OP_MOV operlist_2 {
 			struct instruction *insn = xmalloc(sizeof(struct instruction));
 			insn->op = OP_MOV;
@@ -933,6 +962,14 @@
 		  }
 		;
 
+insn_jzxh	: OP_JZXH operlist_2_jump_human {
+			struct instruction *insn = xmalloc(sizeof(struct instruction));
+			insn->op = OP_JZXH;
+			insn->operands = $2;
+			$$ = insn;
+		  }
+		;
+
 insn_jnzx	: OP_JNZX extended_operlist {
 			struct instruction *insn = xmalloc(sizeof(struct instruction));
 			insn->op = OP_JNZX;
@@ -941,6 +978,14 @@
 		  }
 		;
 
+insn_jnzxh	: OP_JNZXH operlist_2_jump_human {
+			struct instruction *insn = xmalloc(sizeof(struct instruction));
+			insn->op = OP_JNZXH;
+			insn->operands = $2;
+			$$ = insn;
+		  }
+		;
+
 insn_jdn	: OP_JDN operlist_3 {
 			struct instruction *insn = xmalloc(sizeof(struct instruction));
 			insn->op = OP_JDN;
@@ -1217,6 +1262,196 @@
 		  }
 		;
 
+operlist_2_jump_human	: operand_shift_operand_mask COMMA operand {
+			struct operlist *ol = $1;
+			ol->oper[3] = store_oper_sanity($3);
+			$$ = ol;
+		  }
+		;
+
+/* all the following could be implemented:
+   Y => implemented N => raise error
+	N 0xabcdefgh
+	N 0xabcdefgh & BITMASK
+	Y REG12 & BITMASK
+	Y (REG12 << 16) & BITMASK
+	Y (REG31 << 16 | REG12) & BITMASK
+	N (REG12 << 16| 0xabcd) & BITMASK
+	N (0xabcd0000 | REG12) & BITMASK
+*/
+operand_shift_operand_mask	: imm {
+			yyerror("Special jump not yet implemented");
+		  }
+		| imm BITW_AND imm {
+			yyerror("Special jump not yet implemented");
+		  }
+		| operandh BITW_AND imm {
+			struct operlist *ol = xmalloc(sizeof(struct operlist));
+			ol->oper[0] = $1;
+			ol->oper[1] = xmalloc(sizeof(struct operand));
+			ol->oper[1]->type = OPER_IMM;
+			ol->oper[1]->u.imm = xmalloc(sizeof(struct immediate));
+			ol->oper[1]->u.imm->imm = 0;
+			ol->oper[2] = xmalloc(sizeof(struct operand));
+			ol->oper[2]->type = OPER_IMM;
+			ol->oper[2]->u.imm = $3;
+			$$ = ol;
+		  }
+		| PAREN_OPEN operandh LEFTSHIFT imm PAREN_CLOSE BITW_AND imm {
+			struct operlist *ol = xmalloc(sizeof(struct operlist));
+			struct immediate *imm = $4;
+			if(imm->imm != 16)
+				yyerror("Only 16 bit shift allowed here");
+			ol->oper[0] = xmalloc(sizeof(struct operand));
+			ol->oper[0]->type = OPER_IMM;
+			ol->oper[0]->u.imm = xmalloc(sizeof(struct immediate));
+			ol->oper[0]->u.imm->imm = 0;
+			ol->oper[1] = $2;
+			ol->oper[2] = xmalloc(sizeof(struct operand));
+			ol->oper[2]->type = OPER_IMM;
+			ol->oper[2]->u.imm = $7;
+			$$ = ol;
+		  }
+		| PAREN_OPEN operandh LEFTSHIFT imm BITW_OR operandh PAREN_CLOSE BITW_AND imm {
+			struct operlist *ol = xmalloc(sizeof(struct operlist));
+			struct immediate *imm = $4;
+			if(imm->imm != 16)
+				yyerror("Only 16 bit shift allowed here");
+			ol->oper[0] = $6;
+			ol->oper[1] = $2;
+			ol->oper[2] = xmalloc(sizeof(struct operand));
+			ol->oper[2]->type = OPER_IMM;
+			ol->oper[2]->u.imm = $9;
+			$$ = ol;
+		  }
+		| PAREN_OPEN operandh LEFTSHIFT imm BITW_OR imm PAREN_CLOSE BITW_AND imm {
+			yyerror("Special jump not yet implemented");
+		  }
+		| PAREN_OPEN operandh BITW_OR imm PAREN_CLOSE BITW_AND imm {
+			yyerror("Special jump not yet implemented");
+		  }
+		;
+
+operlist_3_human	: operand_shift_mask COMMA operand_shift_mask COMMA operand {
+			struct operlist *ol = xmalloc(sizeof(struct operlist));
+			struct operand_shift_mask *xxx = $1;
+			struct operand *shift_xxx = xmalloc(sizeof(struct operand));
+			struct operand *mask_xxx = xmalloc(sizeof(struct operand));
+			struct operand_shift_mask *yyy = $3;
+			struct operand *shift_yyy = xmalloc(sizeof(struct operand));
+			struct operand *mask_yyy = xmalloc(sizeof(struct operand));
+			shift_xxx->type = OPER_RAW;
+			shift_xxx->u.raw = (unsigned long) xxx->shift;
+			mask_xxx->type = OPER_RAW;
+			mask_xxx->u.raw = (unsigned long) xxx->mask;
+			shift_yyy->type = OPER_RAW;
+			shift_yyy->u.raw = (unsigned long) yyy->shift;
+			mask_yyy->type = OPER_RAW;
+			mask_yyy->u.raw = (unsigned long) yyy->mask;
+			ol->oper[0] = xxx->op;
+			ol->oper[1] = shift_xxx; 
+			ol->oper[2] = mask_xxx;
+			ol->oper[3] = yyy->op;
+			ol->oper[4] = shift_yyy;
+			ol->oper[5] = mask_yyy;
+			ol->oper[6] = store_oper_sanity($5);
+			free(xxx);
+			free(yyy);
+			$$ = ol;
+		  }
+		;
+
+/* duplicate some complex_imm rules to avoid parentheses
+	The following are implemented:
+		0x143 || 0x143 & 0x12 || 0x143 & ~0x12
+		REG12 || REG12 & 0x12 || REG12 & ~0x12
+		(REG12 << 0x12) || (REG12 << 0x12) & 0x12 || (REG12 << 0x12) & ~0x12
+*/
+operand_shift_mask	: imm {
+			struct operand_shift_mask *oper = xmalloc(sizeof(struct operand_shift_mask));
+			struct operand *oper_imm = xmalloc(sizeof(struct operand));
+			oper_imm->type = OPER_IMM;
+			oper_imm->u.imm = $1;
+			oper->op = oper_imm;
+			oper->mask = 0xFFFF;
+			oper->shift = 0;
+			$$ = oper;
+		  }
+		| imm BITW_AND imm {
+			struct operand_shift_mask *oper = xmalloc(sizeof(struct operand_shift_mask));
+			struct operand *oper_imm = xmalloc(sizeof(struct operand));
+			struct immediate *mask_imm = $3;
+			oper_imm->type = OPER_IMM;
+			oper_imm->u.imm = $1;
+			oper->op = oper_imm;
+			oper->shift = 0;
+			oper->mask = mask_imm->imm & 0xFFFF;
+			free(mask_imm);
+			$$ = oper;
+		  }
+		| imm BITW_AND BITW_NOT imm {
+			struct operand_shift_mask *oper = xmalloc(sizeof(struct operand_shift_mask));
+			struct operand *oper_imm = xmalloc(sizeof(struct operand));
+			struct immediate *mask_imm = $4;
+			oper_imm->type = OPER_IMM;
+			oper_imm->u.imm = $1;
+			oper->op = oper_imm;
+			oper->shift = 0;
+			oper->mask = (~mask_imm->imm) & 0xFFFF;
+			free(mask_imm);
+			$$ = oper;
+		  }
+		| operand_wwo_shift {
+			struct operand_shift_mask *oper = $1;
+			oper->mask = 0xFFFF;
+			$$ = oper;
+		  }
+		| operand_wwo_shift BITW_AND imm {
+			struct operand_shift_mask *oper = $1;
+			struct immediate *mask_imm = $3;
+			oper->mask = mask_imm->imm;
+			free(mask_imm);
+			$$ = oper;
+		  }
+		| operand_wwo_shift BITW_AND BITW_NOT imm {
+			struct operand_shift_mask *oper = $1;
+			struct immediate *mask_imm = $4;
+			oper->mask = (~mask_imm->imm) & 0xFFFF;
+			free(mask_imm);
+			$$ = oper;
+		  }
+		;
+
+operand_wwo_shift	: operandh {
+			struct operand_shift_mask *oper = xmalloc(sizeof(struct operand_shift_mask));
+			oper->op = $1;
+			oper->shift = 0;
+			$$ = oper;
+		  }
+		| PAREN_OPEN operandh LEFTSHIFT imm PAREN_CLOSE {
+			struct operand_shift_mask *oper = xmalloc(sizeof(struct operand_shift_mask));
+			struct immediate *shift_imm = $4;
+			oper->op = $2;
+			oper->shift = shift_imm->imm;
+			free(shift_imm);
+			$$ = oper;
+		  }
+		;
+
+operandh	: reg {
+			struct operand *oper = xmalloc(sizeof(struct operand));
+			oper->type = OPER_REG;
+			oper->u.reg = $1;
+			$$ = oper;
+		  }
+		| mem {
+			struct operand *oper = xmalloc(sizeof(struct operand));
+			oper->type = OPER_MEM;
+			oper->u.mem = $1;
+			$$ = oper;
+		  }
+		;
+
 operand		: reg {
 			struct operand *oper = xmalloc(sizeof(struct operand));
 			oper->type = OPER_REG;
Index: b43-tools/assembler/scanner.l
===================================================================
--- b43-tools/assembler/scanner.l	2011-09-11 19:59:43.000000000 +0200
+++ b43-tools/assembler/scanner.l	2011-11-11 18:15:47.000000000 +0100
@@ -105,6 +105,7 @@
 rr			{ update_lineinfo(); return OP_RR; }
 nand			{ update_lineinfo(); return OP_NAND; }
 orx			{ update_lineinfo(); return OP_ORX; }
+orxh			{ update_lineinfo(); return OP_ORXH; }
 mov			{ update_lineinfo(); return OP_MOV; }
 
 jmp			{ update_lineinfo(); return OP_JMP; }
@@ -127,7 +128,9 @@
 jdp			{ update_lineinfo(); return OP_JDP; }
 jdnz			{ update_lineinfo(); return OP_JDNZ; }
 jzx			{ update_lineinfo(); return OP_JZX; }
+jzxh			{ update_lineinfo(); return OP_JZXH; }
 jnzx			{ update_lineinfo(); return OP_JNZX; }
+jnzxh			{ update_lineinfo(); return OP_JNZXH; }
 jext			{ update_lineinfo(); return OP_JEXT; }
 jnext			{ update_lineinfo(); return OP_JNEXT; }
 
Index: b43-tools/assembler/test.asm
===================================================================
--- b43-tools/assembler/test.asm	2011-09-12 17:03:22.000000000 +0200
+++ b43-tools/assembler/test.asm	2011-11-12 17:09:04.000000000 +0100
@@ -72,6 +72,11 @@
 
 	orx	7,8,r0,r1,r2	/* eXtended OR */
 
+	orxh	0x10, r1 & ~0x30, r2	/* r2 = 0x10 | (r1 & ~0x30) */
+	orxh	0, r1 & ~0xFFF0, r2	/* r2 = r1 & ~0xFFF0 */
+	orxh	r1 & 0x7FFF, 0 & ~0x7FFF, r2		/* r2 = r1 & 0x7FFF */
+	orxh	(r1 << 8) & 0x0100, r2 & ~0x0100, r2	/* r2 = (r1 << 8) & 0x0100 | r2 & ~0x0100 */
+
 	/* Copy instruction. This is a virtual instruction
 	 * translated to more lowlevel stuff like OR. */
 	mov	r0,r2		/* copy data */
@@ -100,6 +105,13 @@
 	jzx	7,8,r0,r1,label	/* Jump if zero after shift and mask */
 	jnzx	7,8,r0,r1,label	/* Jump if nonzero after shift and mask */
 
+	jzxh	r12 & 0x18, label  /* jump if result is zero */
+	jzxh	(r12 << 16) & 0x001FFFC0, label    /* jump if result is zero */
+	jzxh	(r12 << 16 | r13) & 0x1F000, label /* jump if result is zero */
+	jnzxh	r12 & 0x18, label  /* jump if result is non zero */
+	jnzxh	(r12 << 16) & 0x001FFFC0, label    /* jump if result is non zero */
+	jnzxh	(r12 << 16 | r13) & 0x1F000, label /* jump if result is non zero */
+
 	/* jump on external conditions */
 	jext	ECOND_MAC_ON,label  /* jump if external condition is TRUE */
 	jnext	ECOND_MAC_ON,label  /* jump if external condition is FALSE */
--- b43-tools/assembler/README	2011-11-12 17:53:50.000000000 +0100
+++ b43-tools/assembler/README	2011-11-12 17:53:14.000000000 +0100
@@ -43,7 +43,9 @@
 ret       | lrX,lrY    | Store PC, ret from func         | lrX=PC; PC=lrY
 rets      |            | ret from function               | stack->PC
 jzx       | M,S,A,B,l  | Jump if zero after shift + mask |
+jzxh      | A,l        | Human readable alias for jzx    | See detailed docs
 jnzx      | M,S,A,B,l  | Jump if nonzero after shift+msk |
+jnzxh     | A,l        | Human readable alias for jnzx   | See detailed docs
 jext      | E,A,B,l    | Jump if External Condition true | if(E) PC=l
 jnext     | E,A,B,l    | Jump if External Condition false| if(!E) PC=l
 
@@ -66,6 +68,7 @@
 rr        | A,B,rD     | Rotate right                    | rD=rrot(A, B bits)
 nand      | A,B,rD     | Clear bits (notmask+and)        | rD=A&(~B)
 orx       | M,S,A,B,rD | OR with shift and select        | See detailed docs
+orxh      | A,B,rD     | Human readable alias for orx    | See detailed docs
 
 Other instructions:
 nap       | none       | Sleep until event               | See detailed docs

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] b43-asm: Add 3 new virtual instructions.
  2011-11-12 17:31 [PATCH] b43-asm: Add 3 new virtual instructions francesco.gringoli at ing.unibs.it
@ 2011-11-12 18:05 ` Michael Büsch
  2011-11-12 19:03   ` francesco.gringoli at ing.unibs.it
  0 siblings, 1 reply; 6+ messages in thread
From: Michael Büsch @ 2011-11-12 18:05 UTC (permalink / raw)
  To: b43-dev

On Sat, 12 Nov 2011 18:31:21 +0100
francesco.gringoli at ing.unibs.it wrote:

> 	orxh	(r1 << 8) & 0x0100, r2 & ~0x0100, r2

This is not really going to fly. If you want this highlevel stuff, you
should port a C compiler to the architecture.
This is assembly. It doesn't know about reg<<imm or similar stuff.

-- 
Greetings, Michael.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] b43-asm: Add 3 new virtual instructions.
  2011-11-12 18:05 ` Michael Büsch
@ 2011-11-12 19:03   ` francesco.gringoli at ing.unibs.it
  2011-11-12 19:16     ` Michael Büsch
  0 siblings, 1 reply; 6+ messages in thread
From: francesco.gringoli at ing.unibs.it @ 2011-11-12 19:03 UTC (permalink / raw)
  To: b43-dev

On Nov 12, 2011, at 7:05 PM, Michael B?sch wrote:

> On Sat, 12 Nov 2011 18:31:21 +0100
> francesco.gringoli at ing.unibs.it wrote:
> 
>> 	orxh	(r1 << 8) & 0x0100, r2 & ~0x0100, r2
> 
> This is not really going to fly. If you want this highlevel stuff, you
> should port a C compiler to the architecture.
> This is assembly. It doesn't know about reg<<imm or similar stuff.
Yes, you are right and, in fact, the patched assembler will just accept only what the cpu may execute, I does not pretend to be a C compiler. It's just another way for assembling "or with shift and select" (or jzx), and this way really enhances the readability of the assembly code. Give it a try :-).

If I'm not wrong, it's like "mov 0x1234, r1": such instruction doesn't exist but the assembler accepts it and converts to "orx 7, 8, 0x12, 0x34, r1". So why not adding more assembly options so that the code can be easily understood? Consider these lines

	orx		0, 5, 0x001, SPR_BRC, SPR_BRC
	orx		0, 3, 0x000, SPR_BRC, SPR_BRC
	orx		1, 0, GP_REG1, SPR_TXE0_PHY_CTL, SPR_TXE0_PHY_CTL;

and compare them to

#define FRAME_BURST 0x0020
#define CONTENTION_PARAM_MODIFIED 0x0008
#define FRAME_ENCODING 0x0003
	orxh	FRAME_BURST, SPR_BRC & ~FRAME_BURST, SPR_BRC
	orxh	0x0000, SPR_BRC & ~CONTENTION_PARAM_MODIFIED, SPR_BRC
	orxh	r1 & FRAME_ENCODING, SPR_TXE0_PHY_CTL & ~ FRAME_ENCODING, SPR_TXE0_PHY_CTL

Regards,
-Francesco

> 
> -- 
> Greetings, Michael.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] b43-asm: Add 3 new virtual instructions.
  2011-11-12 19:03   ` francesco.gringoli at ing.unibs.it
@ 2011-11-12 19:16     ` Michael Büsch
  2011-11-12 20:12       ` francesco.gringoli at ing.unibs.it
  0 siblings, 1 reply; 6+ messages in thread
From: Michael Büsch @ 2011-11-12 19:16 UTC (permalink / raw)
  To: b43-dev

On Sat, 12 Nov 2011 20:03:36 +0100
francesco.gringoli at ing.unibs.it wrote:

> On Nov 12, 2011, at 7:05 PM, Michael B?sch wrote:
> 
> > On Sat, 12 Nov 2011 18:31:21 +0100
> > francesco.gringoli at ing.unibs.it wrote:
> > 
> >> 	orxh	(r1 << 8) & 0x0100, r2 & ~0x0100, r2
> > 
> > This is not really going to fly. If you want this highlevel stuff, you
> > should port a C compiler to the architecture.
> > This is assembly. It doesn't know about reg<<imm or similar stuff.
> Yes, you are right and, in fact, the patched assembler will just accept only what the cpu may execute, I does not pretend to be a C compiler. It's just another way for assembling "or with shift and select" (or jzx), and this way really enhances the readability of the assembly code. Give it a try :-).
> 
> If I'm not wrong, it's like "mov 0x1234, r1"

No.
It crosses the line where it does (pseudo)operations (like shift, and, or, etc..)
on non-const (non-immediate) stuff.

Just do a preprocessor or something like that, that translates your pseudo-insns
to real insns. Alternatively port a small C compiler.

I also don't think that this is easier to read for people familiar to the CPU. And
you have to be familiar to the CPU when writing code for it.

I won't merge this. No way.

The "/* duplicate some complex_imm rules to avoid parentheses" part also is not
really merge-able as-is. yacc knows about operator precedence. If you want operator
precedence (to get rid of parenthesis), just use this yacc feature to implement this.

-- 
Greetings, Michael.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] b43-asm: Add 3 new virtual instructions.
  2011-11-12 19:16     ` Michael Büsch
@ 2011-11-12 20:12       ` francesco.gringoli at ing.unibs.it
  2011-11-12 20:18         ` Gábor Stefanik
  0 siblings, 1 reply; 6+ messages in thread
From: francesco.gringoli at ing.unibs.it @ 2011-11-12 20:12 UTC (permalink / raw)
  To: b43-dev

On Nov 12, 2011, at 8:16 PM, Michael B?sch wrote:

> On Sat, 12 Nov 2011 20:03:36 +0100
> francesco.gringoli at ing.unibs.it wrote:
> 
>> On Nov 12, 2011, at 7:05 PM, Michael B?sch wrote:
>> 
>>> On Sat, 12 Nov 2011 18:31:21 +0100
>>> francesco.gringoli at ing.unibs.it wrote:
>>> 
>>>> 	orxh	(r1 << 8) & 0x0100, r2 & ~0x0100, r2
>>> 
>>> This is not really going to fly. If you want this highlevel stuff, you
>>> should port a C compiler to the architecture.
>>> This is assembly. It doesn't know about reg<<imm or similar stuff.
>> Yes, you are right and, in fact, the patched assembler will just accept only what the cpu may execute, I does not pretend to be a C compiler. It's just another way for assembling "or with shift and select" (or jzx), and this way really enhances the readability of the assembly code. Give it a try :-).
>> 
>> If I'm not wrong, it's like "mov 0x1234, r1"
> 
> No.
> It crosses the line where it does (pseudo)operations (like shift, and, or, etc..)
> on non-const (non-immediate) stuff.

> Just do a preprocessor or something like that, that translates your pseudo-insns
> to real insns. Alternatively port a small C compiler.
> 
> I also don't think that this is easier to read for people familiar to the CPU. And
> you have to be familiar to the CPU when writing code for it.
I initially started with a pre-processor but I soon realized that those three instructions were the only one whose readability could have been improved by the preprocessor itself.

> I won't merge this. No way.
Ok, anyway I urge to share with other researchers  a new version of the standard ucode and for the moment I don't have more time to spend on the "preprocessor". I'm sorry but the new ucode source will require the patched assembler. As soon as I have finished some work on the N-PHY firmware I will come back to the preprocessor.

> The "/* duplicate some complex_imm rules to avoid parentheses" part also is not
> really merge-able as-is. yacc knows about operator precedence. If you want operator
> precedence (to get rid of parenthesis), just use this yacc feature to implement this.
Yes, I did it this way because "[reg|mem] << imm" is not assembly (as you say :-) ) and the assembler strictly checks that such syntax is used only with "orxh".

Regards,
-Francesco

> 
> -- 
> Greetings, Michael.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] b43-asm: Add 3 new virtual instructions.
  2011-11-12 20:12       ` francesco.gringoli at ing.unibs.it
@ 2011-11-12 20:18         ` Gábor Stefanik
  0 siblings, 0 replies; 6+ messages in thread
From: Gábor Stefanik @ 2011-11-12 20:18 UTC (permalink / raw)
  To: b43-dev

On Sat, Nov 12, 2011 at 9:12 PM,  <francesco.gringoli@ing.unibs.it> wrote:
> On Nov 12, 2011, at 8:16 PM, Michael B?sch wrote:
>
>> On Sat, 12 Nov 2011 20:03:36 +0100
>> francesco.gringoli at ing.unibs.it wrote:
>>
>>> On Nov 12, 2011, at 7:05 PM, Michael B?sch wrote:
>>>
>>>> On Sat, 12 Nov 2011 18:31:21 +0100
>>>> francesco.gringoli at ing.unibs.it wrote:
>>>>
>>>>> ? ?orxh ? ?(r1 << 8) & 0x0100, r2 & ~0x0100, r2
>>>>
>>>> This is not really going to fly. If you want this highlevel stuff, you
>>>> should port a C compiler to the architecture.
>>>> This is assembly. It doesn't know about reg<<imm or similar stuff.
>>> Yes, you are right and, in fact, the patched assembler will just accept only what the cpu may execute, I does not pretend to be a C compiler. It's just another way for assembling "or with shift and select" (or jzx), and this way really enhances the readability of the assembly code. Give it a try :-).
>>>
>>> If I'm not wrong, it's like "mov 0x1234, r1"
>>
>> No.
>> It crosses the line where it does (pseudo)operations (like shift, and, or, etc..)
>> on non-const (non-immediate) stuff.
>
>> Just do a preprocessor or something like that, that translates your pseudo-insns
>> to real insns. Alternatively port a small C compiler.
>>
>> I also don't think that this is easier to read for people familiar to the CPU. And
>> you have to be familiar to the CPU when writing code for it.
> I initially started with a pre-processor but I soon realized that those three instructions were the only one whose readability could have been improved by the preprocessor itself.
>
>> I won't merge this. No way.
> Ok, anyway I urge to share with other researchers ?a new version of the standard ucode and for the moment I don't have more time to spend on the "preprocessor". I'm sorry but the new ucode source will require the patched assembler. As soon as I have finished some work on the N-PHY firmware I will come back to the preprocessor.
>
>> The "/* duplicate some complex_imm rules to avoid parentheses" part also is not
>> really merge-able as-is. yacc knows about operator precedence. If you want operator
>> precedence (to get rid of parenthesis), just use this yacc feature to implement this.
> Yes, I did it this way because "[reg|mem] << imm" is not assembly (as you say :-) ) and the assembler strictly checks that such syntax is used only with "orxh".

Well, in x86, we have "mov eax, es:[bx+di]". A lot more readable than,
say, "mov eax, es, bx, di".

>
> Regards,
> -Francesco
>
>>
>> --
>> Greetings, Michael.
>
>
> _______________________________________________
> b43-dev mailing list
> b43-dev at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/b43-dev
>



-- 
Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-11-12 20:18 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-12 17:31 [PATCH] b43-asm: Add 3 new virtual instructions francesco.gringoli at ing.unibs.it
2011-11-12 18:05 ` Michael Büsch
2011-11-12 19:03   ` francesco.gringoli at ing.unibs.it
2011-11-12 19:16     ` Michael Büsch
2011-11-12 20:12       ` francesco.gringoli at ing.unibs.it
2011-11-12 20:18         ` Gábor Stefanik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox