All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Daney <ddaney.cavm@gmail.com>
To: "Steven J. Hill" <sjhill@mips.com>
Cc: linux-mips@linux-mips.org, ralf@linux-mips.org, cernekee@gmail.com
Subject: Re: [PATCH][RFC] MIPS: microMIPS: Add support to micro-assembler.
Date: Wed, 30 Jan 2013 10:04:41 -0800	[thread overview]
Message-ID: <510960B9.1060800@gmail.com> (raw)
In-Reply-To: <1359514228-2161-1-git-send-email-sjhill@mips.com>

On 01/29/2013 06:50 PM, Steven J. Hill wrote:
> From: "Steven J. Hill" <sjhill@mips.com>
>
> This adds microMIPS instruction support to the micro-assembler.
>
> Signed-off-by: Steven J. Hill <sjhill@mips.com>
> ---
>   arch/mips/mm/uasm.c |  121 +++++++++++++++++++++++++++++++++------------------
>   1 file changed, 78 insertions(+), 43 deletions(-)
>
> diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
> index 942ff6c..13f0ca7 100644
> --- a/arch/mips/mm/uasm.c
> +++ b/arch/mips/mm/uasm.c
> @@ -10,6 +10,7 @@
>    * Copyright (C) 2004, 2005, 2006, 2008	 Thiemo Seufer
>    * Copyright (C) 2005, 2007  Maciej W. Rozycki
>    * Copyright (C) 2006  Ralf Baechle (ralf@linux-mips.org)
> + * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
>    */
>
>   #include <linux/kernel.h>
> @@ -35,27 +36,6 @@ enum fields {
>   	SCIMM = 0x400
>   };
>
> -#define OP_MASK		0x3f
> -#define OP_SH		26
> -#define RS_MASK		0x1f
> -#define RS_SH		21
> -#define RT_MASK		0x1f
> -#define RT_SH		16
> -#define RD_MASK		0x1f
> -#define RD_SH		11
> -#define RE_MASK		0x1f
> -#define RE_SH		6
> -#define IMM_MASK	0xffff
> -#define IMM_SH		0
> -#define JIMM_MASK	0x3ffffff
> -#define JIMM_SH		0
> -#define FUNC_MASK	0x3f
> -#define FUNC_SH		0
> -#define SET_MASK	0x7
> -#define SET_SH		0
> -#define SCIMM_MASK	0xfffff
> -#define SCIMM_SH	6
> -
>   enum opcode {
>   	insn_invalid,
>   	insn_addiu, insn_addu, insn_and, insn_andi, insn_bbit0, insn_bbit1,
> @@ -77,14 +57,17 @@ struct insn {
>   	enum fields fields;
>   };
>
> +/* Register length mask. */
> +#define RX_MASK		0x1f
> +
>   /* This macro sets the non-variable bits of an instruction. */
>   #define M(a, b, c, d, e, f)					\
> -	((a) << OP_SH						\
> -	 | (b) << RS_SH						\
> -	 | (c) << RT_SH						\
> -	 | (d) << RD_SH						\
> -	 | (e) << RE_SH						\
> -	 | (f) << FUNC_SH)
> +	((a) << 26						\
> +	 | (b) << 21						\
> +	 | (c) << 16						\
> +	 | (d) << 11						\
> +	 | (e) << 6						\
> +	 | (f) << 0)
>
>   static struct insn insn_table[] __uasminitdata = {
>   	{ insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
> @@ -158,30 +141,46 @@ static struct insn insn_table[] __uasminitdata = {
>
>   static inline __uasminit u32 build_rs(u32 arg)
>   {
> -	WARN(arg & ~RS_MASK, KERN_WARNING "Micro-assembler field overflow\n");
> +#ifdef CONFIG_CPU_MICROMIPS
> +#define RS_SH		16
> +#else
> +#define RS_SH		21
> +#endif

I wonder if we could get rid of most of these #ifdefs by taking the 
approach used in scripts/recordmcount.{c,h} or scripts/sortextable.{c,h}

That is, move all the code that varies between microMIPS and MIPS to an 
included file.  At the top of that file have a single 
#if...#else...#endif block that defines the constants for each variety.

Then include this file as many times as needed (once or twice) to 
produce the definitions required.

This would allow both a MIPS and microMIPS uasm to exist in the same kernel.

Use Case: Synthesizing VDSO code in a microMIPS kernel.  The kernel 
might be build for microMIPS, but the user space code in the VDSO must 
(by the kernel ABI) be standard MIPS instructions.



>
> -	return (arg & RS_MASK) << RS_SH;
> +	WARN(arg & ~RX_MASK, KERN_WARNING "Micro-assembler field overflow\n");
> +
> +	return (arg & RX_MASK) << RS_SH;
>   }
>
>   static inline __uasminit u32 build_rt(u32 arg)
>   {
> -	WARN(arg & ~RT_MASK, KERN_WARNING "Micro-assembler field overflow\n");
> +#ifdef CONFIG_CPU_MICROMIPS
> +#define RT_SH		21
> +#else
> +#define RT_SH		16
> +#endif
> +
> +	WARN(arg & ~RX_MASK, KERN_WARNING "Micro-assembler field overflow\n");
>
> -	return (arg & RT_MASK) << RT_SH;
> +	return (arg & RX_MASK) << RT_SH;
>   }
>
>   static inline __uasminit u32 build_rd(u32 arg)
>   {
> -	WARN(arg & ~RD_MASK, KERN_WARNING "Micro-assembler field overflow\n");
> +#define RD_SH		11
>
> -	return (arg & RD_MASK) << RD_SH;
> +	WARN(arg & ~RX_MASK, KERN_WARNING "Micro-assembler field overflow\n");
> +
> +	return (arg & RX_MASK) << RD_SH;
>   }
>
>   static inline __uasminit u32 build_re(u32 arg)
>   {
> -	WARN(arg & ~RE_MASK, KERN_WARNING "Micro-assembler field overflow\n");
> +#define RE_SH		6
>
> -	return (arg & RE_MASK) << RE_SH;
> +	WARN(arg & ~RX_MASK, KERN_WARNING "Micro-assembler field overflow\n");
> +
> +	return (arg & RX_MASK) << RE_SH;
>   }
>
>   static inline __uasminit u32 build_simm(s32 arg)
> @@ -194,6 +193,8 @@ static inline __uasminit u32 build_simm(s32 arg)
>
>   static inline __uasminit u32 build_uimm(u32 arg)
>   {
> +#define IMM_MASK	0xffff
> +
>   	WARN(arg & ~IMM_MASK, KERN_WARNING "Micro-assembler field overflow\n");
>
>   	return arg & IMM_MASK;
> @@ -201,32 +202,54 @@ static inline __uasminit u32 build_uimm(u32 arg)
>
>   static inline __uasminit u32 build_bimm(s32 arg)
>   {
> -	WARN(arg > 0x1ffff || arg < -0x20000,
> +#ifdef CONFIG_CPU_MICROMIPS
> +#define BIMM_SHIFT	1
> +#else
> +#define BIMM_SHIFT	2
> +#endif
> +
> +	WARN(arg > (0x1ffff >> (2 - BIMM_SHIFT)) ||
> +	     arg < (-0x20000 >> (2 - BIMM_SHIFT)),
>   	     KERN_WARNING "Micro-assembler field overflow\n");
>
>   	WARN(arg & 0x3, KERN_WARNING "Invalid micro-assembler branch target\n");
>
> -	return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff);
> +	return ((arg < 0) ? (1 << 15) : 0) | ((arg >> BIMM_SHIFT) & 0x7fff);
>   }
>
>   static inline __uasminit u32 build_jimm(u32 arg)
>   {
> -	WARN(arg & ~(JIMM_MASK << 2),
> +#define JIMM_MASK	0x3ffffff
> +#ifdef CONFIG_CPU_MICROMIPS
> +	arg >>= 1;
> +#else
> +	arg >>= 2;
> +#endif
> +
> +	WARN(arg & ~JIMM_MASK,
>   	     KERN_WARNING "Micro-assembler field overflow\n");
>
> -	return (arg >> 2) & JIMM_MASK;
> +	return (arg & JIMM_MASK);
>   }
>
>   static inline __uasminit u32 build_scimm(u32 arg)
>   {
> -	WARN(arg & ~SCIMM_MASK,
> +#ifdef CONFIG_CPU_MICROMIPS
> +#define SCIMM_SH	6
> +#else
> +#define SCIMM_SH	0
> +#endif
> +
> +	WARN(arg & ~(0xfffff >> SCIMM_SH),
>   	     KERN_WARNING "Micro-assembler field overflow\n");
>
> -	return (arg & SCIMM_MASK) << SCIMM_SH;
> +	return (arg & ((0xfffff >> SCIMM_SH) << (SCIMM_SH + 10)));
>   }
>
>   static inline __uasminit u32 build_func(u32 arg)
>   {
> +#define FUNC_MASK	0x3f
> +
>   	WARN(arg & ~FUNC_MASK, KERN_WARNING "Micro-assembler field overflow\n");
>
>   	return arg & FUNC_MASK;
> @@ -234,6 +257,8 @@ static inline __uasminit u32 build_func(u32 arg)
>
>   static inline __uasminit u32 build_set(u32 arg)
>   {
> +#define SET_MASK	0x7
> +
>   	WARN(arg & ~SET_MASK, KERN_WARNING "Micro-assembler field overflow\n");
>
>   	return arg & SET_MASK;
> @@ -245,6 +270,11 @@ static inline __uasminit u32 build_set(u32 arg)
>    */
>   static void __uasminit build_insn(u32 **buf, enum opcode opc, ...)
>   {
> +#if defined(CONFIG_CPU_MICROMIPS) && defined(CONFIG_CPU_LITTLE_ENDIAN)
> +#define OP_SHIFT	16
> +#else
> +#define OP_SHIFT	0
> +#endif
>   	struct insn *ip = NULL;
>   	unsigned int i;
>   	va_list ap;
> @@ -285,7 +315,7 @@ static void __uasminit build_insn(u32 **buf, enum opcode opc, ...)
>   		op |= build_scimm(va_arg(ap, u32));
>   	va_end(ap);
>
> -	**buf = op;
> +	**buf = ((op & 0xffff) << OP_SHIFT) | (op >> OP_SHIFT);
>   	(*buf)++;
>   }
>
> @@ -555,12 +585,17 @@ UASM_EXPORT_SYMBOL(uasm_r_mips_pc16);
>   static inline void __uasminit
>   __resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
>   {
> +#if defined(CONFIG_CPU_MICROMIPS) && defined(CONFIG_CPU_LITTLE_ENDIAN)
> +#define REL_SHIFT	16
> +#else
> +#define REL_SHIFT	0
> +#endif
>   	long laddr = (long)lab->addr;
>   	long raddr = (long)rel->addr;
>
>   	switch (rel->type) {
>   	case R_MIPS_PC16:
> -		*rel->addr |= build_bimm(laddr - (raddr + 4));
> +		*rel->addr |= (build_bimm(laddr - (raddr + 4)) << REL_SHIFT);
>   		break;
>
>   	default:
>

  parent reply	other threads:[~2013-01-30 18:04 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-30  2:50 [PATCH][RFC] MIPS: microMIPS: Add support to micro-assembler Steven J. Hill
2013-01-30  2:52 ` Hill, Steven
2013-01-30 18:04 ` David Daney [this message]
2013-02-04 16:06   ` Hill, Steven

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=510960B9.1060800@gmail.com \
    --to=ddaney.cavm@gmail.com \
    --cc=cernekee@gmail.com \
    --cc=linux-mips@linux-mips.org \
    --cc=ralf@linux-mips.org \
    --cc=sjhill@mips.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.