|
@@ -0,0 +1,253 @@
|
|
|
|
+https://github.com/jcmvbkbc/gcc-xtensa/commit/6b0c9f92fb8e11c6be098febb4f502f6af37cd35.patch
|
|
|
|
+
|
|
|
|
+From 6b0c9f92fb8e11c6be098febb4f502f6af37cd35 Mon Sep 17 00:00:00 2001
|
|
|
|
+From: Max Filippov <jcmvbkbc@gmail.com>
|
|
|
|
+Date: Thu, 11 Jun 2015 17:56:57 +0300
|
|
|
|
+Subject: [PATCH] WIP: xtensa: add -mforce-l32
|
|
|
|
+
|
|
|
|
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
|
|
|
|
+---
|
|
|
|
+ gcc/config/xtensa/constraints.md | 15 ++++++++++++
|
|
|
|
+ gcc/config/xtensa/xtensa.c | 53 +++++++++++++++++++++++++++++++++++++++-
|
|
|
|
+ gcc/config/xtensa/xtensa.md | 49 ++++++++++++++++++++-----------------
|
|
|
|
+ gcc/config/xtensa/xtensa.opt | 4 +++
|
|
|
|
+ 4 files changed, 98 insertions(+), 23 deletions(-)
|
|
|
|
+
|
|
|
|
+diff --git a/gcc/config/xtensa/constraints.md b/gcc/config/xtensa/constraints.md
|
|
|
|
+index 30f4c1f..5fd9337 100644
|
|
|
|
+--- a/gcc/config/xtensa/constraints.md
|
|
|
|
++++ b/gcc/config/xtensa/constraints.md
|
|
|
|
+@@ -137,3 +137,18 @@
|
|
|
|
+ (and (match_code "reg")
|
|
|
|
+ (match_test "reload_in_progress
|
|
|
|
+ && REGNO (op) >= FIRST_PSEUDO_REGISTER"))))
|
|
|
|
++
|
|
|
|
++(define_constraint "Y"
|
|
|
|
++ "Memory that is not in a literal pool."
|
|
|
|
++ (ior (and (and (match_code "mem")
|
|
|
|
++ (match_test "! constantpool_mem_p (op)"))
|
|
|
|
++ (match_test "!TARGET_FORCE_L32"))
|
|
|
|
++ (and (match_code "reg")
|
|
|
|
++ (match_test "reload_in_progress
|
|
|
|
++ && REGNO (op) >= FIRST_PSEUDO_REGISTER"))))
|
|
|
|
++
|
|
|
|
++(define_constraint "Z"
|
|
|
|
++ "Memory that is not in a literal pool."
|
|
|
|
++ (and (and (match_code "mem")
|
|
|
|
++ (match_test "! constantpool_mem_p (op)"))
|
|
|
|
++ (match_test "TARGET_FORCE_L32")))
|
|
|
|
+diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
|
|
|
|
+index d8c5b41..559b181 100644
|
|
|
|
+--- a/gcc/config/xtensa/xtensa.c
|
|
|
|
++++ b/gcc/config/xtensa/xtensa.c
|
|
|
|
+@@ -1824,7 +1824,8 @@ xtensa_legitimate_address_p (machine_mode mode, rtx addr, bool strict)
|
|
|
|
+ return true;
|
|
|
|
+
|
|
|
|
+ /* Check for "register + offset" addressing. */
|
|
|
|
+- if (GET_CODE (addr) == PLUS)
|
|
|
|
++ if (GET_CODE (addr) == PLUS &&
|
|
|
|
++ (!TARGET_FORCE_L32 || (mode != HImode && mode != QImode)))
|
|
|
|
+ {
|
|
|
|
+ rtx xplus0 = XEXP (addr, 0);
|
|
|
|
+ rtx xplus1 = XEXP (addr, 1);
|
|
|
|
+@@ -2308,6 +2309,8 @@ printx (FILE *file, signed int val)
|
|
|
|
+ fprintf (file, "0x%x", val);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
++static void
|
|
|
|
++output_address_base (FILE *file, rtx addr);
|
|
|
|
+
|
|
|
|
+ void
|
|
|
|
+ print_operand (FILE *file, rtx x, int letter)
|
|
|
|
+@@ -2317,6 +2320,13 @@ print_operand (FILE *file, rtx x, int letter)
|
|
|
|
+
|
|
|
|
+ switch (letter)
|
|
|
|
+ {
|
|
|
|
++ case 'B':
|
|
|
|
++ if (GET_CODE (x) == MEM)
|
|
|
|
++ output_address_base (file, XEXP (x, 0));
|
|
|
|
++ else
|
|
|
|
++ output_operand_lossage ("invalid %%B value");
|
|
|
|
++ break;
|
|
|
|
++
|
|
|
|
+ case 'D':
|
|
|
|
+ if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
|
|
|
|
+ fprintf (file, "%s", reg_names[xt_true_regnum (x) + 1]);
|
|
|
|
+@@ -2450,6 +2460,47 @@ print_operand (FILE *file, rtx x, int letter)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
++static void
|
|
|
|
++output_address_base (FILE *file, rtx addr)
|
|
|
|
++{
|
|
|
|
++ switch (GET_CODE (addr))
|
|
|
|
++ {
|
|
|
|
++ default:
|
|
|
|
++ fatal_insn ("invalid address", addr);
|
|
|
|
++ break;
|
|
|
|
++
|
|
|
|
++ case REG:
|
|
|
|
++ fprintf (file, "%s", reg_names [REGNO (addr)]);
|
|
|
|
++ break;
|
|
|
|
++
|
|
|
|
++ case PLUS:
|
|
|
|
++ {
|
|
|
|
++ rtx reg = (rtx)0;
|
|
|
|
++ rtx offset = (rtx)0;
|
|
|
|
++ rtx arg0 = XEXP (addr, 0);
|
|
|
|
++ rtx arg1 = XEXP (addr, 1);
|
|
|
|
++
|
|
|
|
++ if (GET_CODE (arg0) == REG)
|
|
|
|
++ {
|
|
|
|
++ reg = arg0;
|
|
|
|
++ offset = arg1;
|
|
|
|
++ }
|
|
|
|
++ else if (GET_CODE (arg1) == REG)
|
|
|
|
++ {
|
|
|
|
++ reg = arg1;
|
|
|
|
++ offset = arg0;
|
|
|
|
++ }
|
|
|
|
++ else
|
|
|
|
++ fatal_insn ("no register in address", addr);
|
|
|
|
++
|
|
|
|
++ if (CONSTANT_P (offset))
|
|
|
|
++ fprintf (file, "%s", reg_names [REGNO (reg)]);
|
|
|
|
++ else
|
|
|
|
++ fatal_insn ("address offset not a constant", addr);
|
|
|
|
++ }
|
|
|
|
++ break;
|
|
|
|
++ }
|
|
|
|
++}
|
|
|
|
+
|
|
|
|
+ /* A C compound statement to output to stdio stream STREAM the
|
|
|
|
+ assembler syntax for an instruction operand that is a memory
|
|
|
|
+diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
|
|
|
|
+index a577aa3..f56c45e 100644
|
|
|
|
+--- a/gcc/config/xtensa/xtensa.md
|
|
|
|
++++ b/gcc/config/xtensa/xtensa.md
|
|
|
|
+@@ -532,26 +532,28 @@
|
|
|
|
+ ;; Zero-extend instructions.
|
|
|
|
+
|
|
|
|
+ (define_insn "zero_extendhisi2"
|
|
|
|
+- [(set (match_operand:SI 0 "register_operand" "=a,a")
|
|
|
|
+- (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))]
|
|
|
|
++ [(set (match_operand:SI 0 "register_operand" "=a,a,a")
|
|
|
|
++ (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,Y,Z")))]
|
|
|
|
+ ""
|
|
|
|
+ "@
|
|
|
|
+ extui\t%0, %1, 0, 16
|
|
|
|
+- l16ui\t%0, %1"
|
|
|
|
+- [(set_attr "type" "arith,load")
|
|
|
|
++ l16ui\t%0, %1
|
|
|
|
++ ssa8l\t%B1 ; srli\t%0, %B1, 2 ; slli\t%0, %0, 2 ; l32i\t%0, %0, 0 ; srl\t%0, %0 ; extui\t%0, %0, 0, 16"
|
|
|
|
++ [(set_attr "type" "arith,load,load")
|
|
|
|
+ (set_attr "mode" "SI")
|
|
|
|
+- (set_attr "length" "3,3")])
|
|
|
|
++ (set_attr "length" "3,3,18")])
|
|
|
|
+
|
|
|
|
+ (define_insn "zero_extendqisi2"
|
|
|
|
+- [(set (match_operand:SI 0 "register_operand" "=a,a")
|
|
|
|
+- (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))]
|
|
|
|
++ [(set (match_operand:SI 0 "register_operand" "=a,a,a")
|
|
|
|
++ (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,Y,Z")))]
|
|
|
|
+ ""
|
|
|
|
+ "@
|
|
|
|
+ extui\t%0, %1, 0, 8
|
|
|
|
+- l8ui\t%0, %1"
|
|
|
|
+- [(set_attr "type" "arith,load")
|
|
|
|
++ l8ui\t%0, %1
|
|
|
|
++ ssa8l\t%B1 ; srli\t%0, %B1, 2 ; slli\t%0, %0, 2 ; l32i\t%0, %0, 0 ; srl\t%0, %0 ; extui\t%0, %0, 0, 8"
|
|
|
|
++ [(set_attr "type" "arith,load,load")
|
|
|
|
+ (set_attr "mode" "SI")
|
|
|
|
+- (set_attr "length" "3,3")])
|
|
|
|
++ (set_attr "length" "3,3,18")])
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ ;; Sign-extend instructions.
|
|
|
|
+@@ -569,15 +571,16 @@
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ (define_insn "extendhisi2_internal"
|
|
|
|
+- [(set (match_operand:SI 0 "register_operand" "=B,a")
|
|
|
|
+- (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))]
|
|
|
|
++ [(set (match_operand:SI 0 "register_operand" "=B,a,a")
|
|
|
|
++ (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,r,Y")))]
|
|
|
|
+ ""
|
|
|
|
+ "@
|
|
|
|
+ sext\t%0, %1, 15
|
|
|
|
++ slli\t%0, %1, 16 ; srai\t%0, %0, 16
|
|
|
|
+ l16si\t%0, %1"
|
|
|
|
+- [(set_attr "type" "arith,load")
|
|
|
|
++ [(set_attr "type" "arith,arith,load")
|
|
|
|
+ (set_attr "mode" "SI")
|
|
|
|
+- (set_attr "length" "3,3")])
|
|
|
|
++ (set_attr "length" "3,6,3")])
|
|
|
|
+
|
|
|
|
+ (define_expand "extendqisi2"
|
|
|
|
+ [(set (match_operand:SI 0 "register_operand" "")
|
|
|
|
+@@ -796,8 +799,8 @@
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ (define_insn "movhi_internal"
|
|
|
|
+- [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
|
|
|
|
+- (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
|
|
|
|
++ [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,a,U,*a,*A")
|
|
|
|
++ (match_operand:HI 1 "move_operand" "M,d,r,I,Y,Z,r,*A,*r"))]
|
|
|
|
+ "xtensa_valid_move (HImode, operands)"
|
|
|
|
+ "@
|
|
|
|
+ movi.n\t%0, %x1
|
|
|
|
+@@ -805,12 +808,13 @@
|
|
|
|
+ mov\t%0, %1
|
|
|
|
+ movi\t%0, %x1
|
|
|
|
+ %v1l16ui\t%0, %1
|
|
|
|
++ ssa8l\t%B1 ; srli\t%0, %B1, 2 ; slli\t%0, %0, 2 ; %v1l32i\t%0, %0, 0 ; srl\t%0, %0 ; extui\t%0, %0, 0, 16
|
|
|
|
+ %v0s16i\t%1, %0
|
|
|
|
+ rsr\t%0, ACCLO
|
|
|
|
+ wsr\t%1, ACCLO"
|
|
|
|
+- [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
|
|
|
|
++ [(set_attr "type" "move,move,move,move,load,load,store,rsr,wsr")
|
|
|
|
+ (set_attr "mode" "HI")
|
|
|
|
+- (set_attr "length" "2,2,3,3,3,3,3,3")])
|
|
|
|
++ (set_attr "length" "2,2,3,3,3,18,3,3,3")])
|
|
|
|
+
|
|
|
|
+ ;; 8-bit Integer moves
|
|
|
|
+
|
|
|
|
+@@ -824,8 +828,8 @@
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ (define_insn "movqi_internal"
|
|
|
|
+- [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
|
|
|
|
+- (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
|
|
|
|
++ [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,a,U,*a,*A")
|
|
|
|
++ (match_operand:QI 1 "move_operand" "M,d,r,I,Y,Z,r,*A,*r"))]
|
|
|
|
+ "xtensa_valid_move (QImode, operands)"
|
|
|
|
+ "@
|
|
|
|
+ movi.n\t%0, %x1
|
|
|
|
+@@ -833,12 +837,13 @@
|
|
|
|
+ mov\t%0, %1
|
|
|
|
+ movi\t%0, %x1
|
|
|
|
+ %v1l8ui\t%0, %1
|
|
|
|
++ ssa8l\t%B1 ; srli\t%0, %B1, 2 ; slli\t%0, %0, 2 ; %v1l32i\t%0, %0, 0 ; srl\t%0, %0 ; extui\t%0, %0, 0, 8
|
|
|
|
+ %v0s8i\t%1, %0
|
|
|
|
+ rsr\t%0, ACCLO
|
|
|
|
+ wsr\t%1, ACCLO"
|
|
|
|
+- [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
|
|
|
|
++ [(set_attr "type" "move,move,move,move,load,load,store,rsr,wsr")
|
|
|
|
+ (set_attr "mode" "QI")
|
|
|
|
+- (set_attr "length" "2,2,3,3,3,3,3,3")])
|
|
|
|
++ (set_attr "length" "2,2,3,3,3,18,3,3,3")])
|
|
|
|
+
|
|
|
|
+ ;; Sub-word reloads from the constant pool.
|
|
|
|
+
|
|
|
|
+diff --git a/gcc/config/xtensa/xtensa.opt b/gcc/config/xtensa/xtensa.opt
|
|
|
|
+index 2fd6cee..02020d2 100644
|
|
|
|
+--- a/gcc/config/xtensa/xtensa.opt
|
|
|
|
++++ b/gcc/config/xtensa/xtensa.opt
|
|
|
|
+@@ -41,3 +41,7 @@ Intersperse literal pools with code in the text section
|
|
|
|
+ mserialize-volatile
|
|
|
|
+ Target Report Mask(SERIALIZE_VOLATILE)
|
|
|
|
+ -mno-serialize-volatile Do not serialize volatile memory references with MEMW instructions
|
|
|
|
++
|
|
|
|
++mforce-l32
|
|
|
|
++Target Report Mask(FORCE_L32)
|
|
|
|
++Use l32i to access 1- and 2-byte quantities in memory instead of l8ui/l16ui
|