[llvm-commits] CVS: llvm/lib/Reoptimizer/BinInterface/construct.cpp emit.cpp regmask.h select.cpp sparc9.h sparcpriv.h test.cpp analyze.cpp analyze.h bitmath.h fvector.h salloc.cpp salloc.h sparcbin.cpp sparcbin.h sparcdis.cpp sparcdis.h main.cpp sparc9.hp
Cameron Buschardt
buschard at cs.uiuc.edu
Sat Dec 14 19:33:00 PST 2002
Changes in directory llvm/lib/Reoptimizer/BinInterface:
construct.cpp added (r1.1)
emit.cpp added (r1.1)
regmask.h added (r1.1)
select.cpp added (r1.1)
sparc9.h updated: 1.6 -> 1.7
sparcpriv.h added (r1.1)
test.cpp added (r1.1)
analyze.cpp updated: 1.4 -> 1.5
analyze.h updated: 1.3 -> 1.4
bitmath.h updated: 1.3 -> 1.4
fvector.h updated: 1.3 -> 1.4
salloc.cpp updated: 1.1 -> 1.2
salloc.h updated: 1.1 -> 1.2
sparcbin.cpp updated: 1.1 -> 1.2
sparcbin.h updated: 1.1 -> 1.2
sparcdis.cpp updated: 1.4 -> 1.5
sparcdis.h updated: 1.3 -> 1.4
main.cpp (r1.1) removed
sparc9.hp (r1.1) removed
---
Log message:
* Fixes made to disassembler to handle hybrid register-label
* Stack allocation and spilling code completed
* broke register allocation, construction, and emit code into seperate files
* added better liveout handling code (now no problems are caused by claiming a value is liveout when it isn't)
---
Diffs of the changes:
Index: llvm/lib/Reoptimizer/BinInterface/sparc9.h
diff -u /dev/null llvm/lib/Reoptimizer/BinInterface/sparc9.h:1.7
--- /dev/null Sat Dec 14 19:32:43 2002
+++ llvm/lib/Reoptimizer/BinInterface/sparc9.h Sat Dec 14 19:31:49 2002
@@ -0,0 +1,399 @@
+//*****************************************************************************
+//
+// Portable SPARC v9 Machine Code Definition Header
+//
+//
+// 2002 Cameron Buschardt
+//*****************************************************************************
+
+//*********************************
+// Register Names
+//*********************************
+#define R_I7 31
+#define R_I6 30
+#define R_I5 29
+#define R_I4 28
+#define R_I3 27
+#define R_I2 26
+#define R_I1 25
+#define R_I0 24
+
+#define R_L7 23
+#define R_L6 22
+#define R_L5 21
+#define R_L4 20
+#define R_L3 19
+#define R_L2 18
+#define R_L1 17
+#define R_L0 16
+
+#define R_O7 15
+#define R_O6 14
+#define R_O5 13
+#define R_O4 12
+#define R_O3 11
+#define R_O2 10
+#define R_O1 9
+#define R_O0 8
+
+#define R_G7 7
+#define R_G6 6
+#define R_G5 5
+#define R_G4 4
+#define R_G3 3
+#define R_G2 2
+#define R_G1 1
+#define R_G0 0
+
+#define R_SP R_O6
+#define R_BP R_I6 // frame pointer
+
+extern char * reg_names[];
+
+//**********************************
+// Instruction bitfield definitions
+//**********************************
+#define INSTR_OP 31:30
+#define INSTR_A 29:29
+#define INSTR_FCN 29:25
+#define INSTR_DISP30 29:0
+#define INSTR_COND_H 28:25
+#define INSTR_RCOND_H 27:25
+#define INSTR_CC1_H 26:26
+#define INSTR_CC0_H 25:25
+#define INSTR_OP2 24:22
+#define INSTR_OP3 24:19
+#define INSTR_CC1_L 21:21
+#define INSTR_D16HI 21:20
+#define INSTR_D16LO 13:0
+#define INSTR_IMM22 21:0
+#define INSTR_DISP22 21:0
+#define INSTR_CC0_L 20:20
+#define INSTR_P 19:19
+#define INSTR_CC2 18:18
+#define INSTR_MOV_CC0 11:11
+#define INSTR_MOV_CC1 12:12
+#define INSTR_DISP19 18:0
+#define INSTR_IMPLDEP 18:0
+#define INSTR_COND_L 17:14
+#define INSTR_I 13:13
+#define INSTR_OPFCC 13:11
+#define INSTR_OPF 13:5
+#define INSTR_X 12:12
+#define INSTR_RCOND_L 12:10
+#define INSTR_IMMASI 12:5
+#define INSTR_SIMM13 12:0
+#define INSTR_OPFLOW_B 10:5
+#define INSTR_OPFLOW_S 9:5
+#define INSTR_SIMM11 10:0
+#define INSTR_SIMM10 9:0
+#define INSTR_CMASK 6:4
+#define INSTR_SWTRAP 6:0
+#define INSTR_SHCNT64 5:0
+#define INSTR_SHCNT32 4:0
+#define INSTR_MMASK 3:0
+
+#define INSTR_RS1 18:14
+#define INSTR_RS2 4:0
+#define INSTR_RD 29:25
+
+
+#define RD_D16(i) ((RD_FLD(i, INSTR_D16HI) << 14) | RD_FLD(i, INSTR_D16LO))
+
+
+//**********************************
+// Op-code classification
+//**********************************
+#define OP_CALL 0x00000001 /* 0b01 */
+#define OP_BRANCH 0x00000000 /* 0b00 */
+#define OP_2 0x00000002 /* 0b10 */
+#define OP_3 0x00000003 /* 0b11 */
+
+//**********************************
+// Branch Class Instructions
+//**********************************
+#define OP2_ILLTRAP 0x00000000 /* 0b000 */ //OP=OP_BRANCH
+#define OP2_NOP 0x00000004 /* 0b100 */ //BRANCH
+#define OP2_SETHI 0x00000004 /* 0b100 */ //BRANCH - uhh? duplicate? DOH =p
+#define OP2_BICC 0x00000002 /* 0b010 */
+#define OP2_BPR 0x00000003 /* 0b011 */
+#define OP2_FB 0x00000006 /* 0b110 */
+#define OP2_FBP 0x00000005 /* 0b101 */
+#define OP2_BPICC 0x00000001 /* 0b001 */
+
+//**********************************
+// Register Condition Codes
+//**********************************
+#define RCOND_RZ 0x00000001 /* 0b001 */
+#define RCOND_RLEZ 0x00000002 /* 0b010 */
+#define RCOND_RNZ 0x00000005 /* 0b101 */
+#define RCOND_RGZ 0x00000006 /* 0b110 */
+#define RCOND_RGEZ 0x00000007 /* 0b111 */
+
+//**********************************
+// FPU Branch Conditions
+//**********************************
+#define COND_FBN 0x00000000 /* 0b0000 */
+#define COND_FBNE 0x00000001 /* 0b0001 */
+#define COND_FBLG 0x00000002 /* 0b0010 */
+#define COND_FBUL 0x00000003 /* 0b0011 */
+#define COND_FBL 0x00000004 /* 0b0100 */
+#define COND_FBUG 0x00000005 /* 0b0101 */
+#define COND_FBG 0x00000006 /* 0b0110 */
+#define COND_FBU 0x00000007 /* 0b0111 */
+#define COND_FBA 0x00000008 /* 0b1000 */
+#define COND_FBE 0x00000009 /* 0b1001 */
+#define COND_FBUE 0x0000000A /* 0b1010 */
+#define COND_FBGE 0x0000000B /* 0b1011 */
+#define COND_FBUGE 0x0000000C /* 0b1100 */
+#define COND_FBLE 0x0000000D /* 0b1101 */
+#define COND_FBULE 0x0000000E /* 0b1110 */
+#define COND_FBO 0x0000000F /* 0b1111 */
+
+//**********************************
+// Integer Branch Conditions
+//**********************************
+#define COND_BN 0x00000000 /* 0b0000 */
+#define COND_BE 0x00000001 /* 0b0001 */
+#define COND_BLE 0x00000002 /* 0b0010 */
+#define COND_BL 0x00000003 /* 0b0011 */
+#define COND_BLEU 0x00000004 /* 0b0100 */
+#define COND_BCS 0x00000005 /* 0b0101 */
+#define COND_BNEG 0x00000006 /* 0b0110 */
+#define COND_BVS 0x00000007 /* 0b0111 */
+#define COND_BA 0x00000008 /* 0b1000 */
+#define COND_BNE 0x00000009 /* 0b1001 */
+#define COND_BG 0x0000000A /* 0b1010 */
+#define COND_BGE 0x0000000B /* 0b1011 */
+#define COND_BGU 0x0000000C /* 0b1100 */
+#define COND_BCC 0x0000000D /* 0b1101 */
+#define COND_BPOS 0x0000000E /* 0b1110 */
+#define COND_BVC 0x0000000F /* 0b1111 */
+
+
+//**********************************
+// Name Lookup tables
+// index is Condition code
+//**********************************
+
+extern char * fcond_names[];
+extern char * icond_names[];
+extern char * rcond_names[];
+
+//**********************************
+// Flag register encoding
+//**********************************
+
+#define FLAG_FCC0 0x00000000 /* 0b000 */
+#define FLAG_FCC1 0x00000001 /* 0b001 */
+#define FLAG_FCC2 0x00000002 /* 0b010 */
+#define FLAG_FCC3 0x00000003 /* 0b011 */
+#define FLAG_ICC 0x00000004 /* 0b100 */
+#define FLAG_XCC 0x00000006 /* 0b110 */
+
+extern char * cc_names[];
+
+
+//**********************************
+// OP_2 class instructions
+//
+// present members:
+// RD, OP3, RS1
+// if I=0
+// RS2
+// else
+// SIMM13
+//**********************************
+
+#define OP3_ADD 0x00000000 /* 0b000000 */
+#define OP3_ADDC 0x00000008 /* 0b001000 */
+#define OP3_AND 0x00000001 /* 0b000001 */
+#define OP3_OR 0x00000002 /* 0b000010 */
+#define OP3_XOR 0x00000003 /* 0b000011 */
+#define OP3_SUB 0x00000004 /* 0b000100 */
+#define OP3_ANDN 0x00000005 /* 0b000101 */
+#define OP3_ORN 0x00000006 /* 0b000110 */
+#define OP3_XNOR 0x00000007 /* 0b000111 */
+#define OP3_SUBC 0x0000000C /* 0b001100 */
+#define OP3_ADDcc 0x00000010 /* 0b010000 */
+#define OP3_ADDCcc 0x00000018 /* 0b011000 */
+#define OP3_ANDcc 0x00000011 /* 0b010001 */
+#define OP3_ORcc 0x00000012 /* 0b010010 */
+#define OP3_XORcc 0x00000013 /* 0b010011 */
+#define OP3_SUBcc 0x00000014 /* 0b010100 */
+#define OP3_ANDNcc 0x00000015 /* 0b010101 */
+#define OP3_ORNcc 0x00000016 /* 0b010110 */
+#define OP3_XNORcc 0x00000017 /* 0b010111 */
+#define OP3_SUBCcc 0x0000001C /* 0b011100 */
+#define OP3_MULX 0x00000009 /* 0b001001 */
+#define OP3_SDIVX 0x0000002D /* 0b101101 */
+#define OP3_UDIVX 0x0000000D /* 0b001101 */
+
+//Op3 members
+#define OP3_CASA 0x0000003C /* 0b111100 */
+#define OP3_CASXA 0x0000003E /* 0b111110 */
+
+//Instructions below generated with:
+//OP=OP_2: RD, OP_3 RS1: {I=0 -> X & RS2 ,I=1 -> {X=0 -> SHCNT32 X=1->SHCNT64 }}
+#define OP3_SLL 0x00000025 /* 0b100101 */
+#define OP3_SRL 0x00000026 /* 0b100110 */
+#define OP3_SRA 0x00000027 /* 0b100111 */
+
+// class OP_3
+#define OP3_STFA 0x00000034 /* 0b110100 */
+#define OP3_STDFA 0x00000037 /* 0b110111 */
+#define OP3_STQFA 0x00000036 /* 0b110110 */
+
+//Instructions below generated with:
+//OP=OP_2: FCN
+#define OP3_DONERETRY 0x0000003E /* 0b111110 */
+#define FCN_DONE 0
+#define FCN_RETRY 1
+
+//These masks are valid for the instructions below
+#define OPF_MASK_ONs 0x00000001 /* 0b0001 */ //these are valid for 'n' field
+#define OPF_MASK_ONd 0x00000002 /* 0b0010 */
+#define OPF_MASK_ONq 0x00000003 /* 0b0011 */
+#define OPF_MASK_TOs 0x00000004 /* 0b0100 */ //these are valid for 't' field
+#define OPF_MASK_TOd 0x00000008 /* 0b1000 */
+#define OPF_MASK_TOq 0x0000000C /* 0b1100 */
+
+#define OPF_MASK_ON 0x00000003 /* 0b0011 */
+#define OPF_MASK_TO 0x0000000C /* 0b1100 */
+
+//Instructions below generated with
+//OP=OP_2: CC1_H, CC0_H, RS1, OPF, RS2
+#define OP3_FCMP 0x00000035 /* 0b110101 */
+#define OPF_FCMPn 0x00000050 /* 0b001010000 */
+#define OPF_FCMPEn 0x00000054 /* 0b001010100 */
+
+//Instructions below generated with
+//OP=OP_2: RD, OP3 RS1, OPF, RS2
+#define OP3_FPU 0x00000034 /* 0b110100 */
+#define OPF_FADDn 0x00000040 /* 0b001000000 */
+#define OPF_FSUBn 0x00000044 /* 0b001000100 */
+#define OPF_FMOVn 0x00000000 /* 0b000000000 */
+#define OPF_FNEGn 0x00000004 /* 0b000000100 */
+#define OPF_FABSn 0x00000008 /* 0b000001000 */
+#define OPF_FMULn 0x00000048 /* 0b001001000 */
+#define OPF_FDIVn 0x0000004C /* 0b001001100 */
+#define OPF_FSQRTn 0x00000028 /* 0b000101000 */
+#define OPF_FsTOx 0x00000081 /* 0b010000001 */
+#define OPF_FsTOi 0x000000D1 /* 0b011010001 */
+#define OPF_FsTOd 0x000000C9 /* 0b011001001 */
+#define OPF_FsTOq 0x000000CD /* 0b011001101 */
+#define OPF_FdTOx 0x00000082 /* 0b010000010 */
+#define OPF_FdTOi 0x000000D2 /* 0b011010010 */
+#define OPF_FdTOs 0x000000C6 /* 0b011000110 */
+#define OPF_FdTOq 0x000000CE /* 0b011001110 */
+#define OPF_FqTOx 0x00000083 /* 0b010000011 */
+#define OPF_FqTOi 0x000000D3 /* 0b011010011 */
+#define OPF_FqTOs 0x000000C7 /* 0b011000111 */
+#define OPF_FqTOd 0x000000CB /* 0b011001011 */
+#define OPF_FxTOt 0x00000080 /* 0b010000000 */
+#define OPF_FiTOt 0x000000C0 /* 0b011000000 */
+#define OPF_FsMULd 0x00000069 /* 0b001101001 */
+#define OPF_FdMULq 0x0000006E /* 0b001101110 */
+
+
+#define OP3_FLUSH 0x0000003B /* 0b111011 */ //OP=OP_2 RS1 {I=0 -> rs2, I=1->simm13}
+#define OP3_FLUSHW 0x0000002B /* 0b101011 */ //OP=OP_2 I = 0
+#define OP3_JMPL 0x00000038 /* 0b111000 */ //OP=OP_2 RD, RS1 {I=0-> RS2, I=1->SIMM13}
+#define OP3_LDFA 0x00000030 /* 0b110000 */ //OP=OP_3 RD, Rs1, {I=0->IMM_ASI, RS2 I=1->SIMM13}
+#define OP3_LDDFA 0x00000033 /* 0b110011 */ //OP=OP_3 RD, Rs1, {I=0->IMM_ASI, RS2 I=1->SIMM13}
+#define OP3_LDQFA 0x00000032 /* 0b110010 */ //OP=OP_3 RD, Rs1, {I=0->IMM_ASI, RS2 I=1->SIMM13}
+
+#define OP3_LDSTUB 0x0000000D /* 0b001101 */ //OP=OP_3 RD, Rs1 {I=0->RS2, I=1->SIMM13}
+#define OP3_STB 0x00000005 /* 0b000101 */
+#define OP3_STH 0x00000006 /* 0b000110 */
+#define OP3_STW 0x00000004 /* 0b000100 */
+#define OP3_STX 0x00000007 /* 0b000111 */
+#define OP3_LDSB 0x00000009 /* 0b001001 */
+#define OP3_LDSH 0x0000000A /* 0b001010 */
+#define OP3_LDSW 0x00000008 /* 0b001000 */
+#define OP3_LDUB 0x00000001 /* 0b000001 */
+#define OP3_LDUH 0x00000002 /* 0b000010 */
+#define OP3_LDUW 0x00000000 /* 0b000000 */
+#define OP3_LDX 0x0000000B /* 0b001011 */
+
+
+
+#define OP3_LDSTUBA 0x0000001D /* 0b011101 */ //OP=OP_3 RD, RS1 {I=0->RS2, IMM_ASI, I=1->SIMM13}
+
+#define OP3_MEMBAR 0x00000028 /* 0b101000 */ //OP=OP_2 CMASK, MMASK //WTF?!?! some bits get set
+
+//These two instructions are FUNKY as hell
+#define OP3_FMOVcc 0x00000035 /* 0b110101 */ //OP=OP_2 RD, COND, OPF_CC, OPF_LOW, RS2
+#define OP3_MOVcc 0x0000002C /* 0b101100 */ //
+
+
+#define OP3_POPC 0x0000002E /* 0b101110 */
+#define OP3_PREFETCH 0x0000002D /* 0b101101 */
+#define OP3_PREFETCHA 0x0000003D /* 0b111101 */
+#define OP3_RETURN 0x00000039 /* 0b111001 */
+#define OP3_SAVE 0x0000003C /* 0b111100 */
+#define OP3_RESTORE 0x0000003D /* 0b111101 */
+
+#define OP3_SAVDRESTD 0x00000031 /* 0b110001 */
+#define FCN_SAVED 0
+#define FCN_RESTORED 1
+
+#define OP3_TRAP 0x0000003A /* 0b111010 */ //integer trap
+
+
+//*****************************************************************************
+// Macros for generating useful instructions
+//*****************************************************************************
+
+// Generic Load worm Reg+Offs
+#define MK_LDX_ROFFS(dreg,regoffs ,stackoffs) \
+ (MK_FLD(INSTR_OP, OP_3) | \
+ MK_FLD(INSTR_RD, dreg) | \
+ MK_FLD(INSTR_OP3, OP3_LDX) | \
+ MK_FLD(INSTR_RS1, regoffs) | \
+ MK_FLD(INSTR_I , 1 ) | \
+ MK_FLD(INSTR_SIMM13, stackoffs))
+
+
+// Load a word from O6/SP + stackoffs into dreg
+#define MK_LDX_STACK(dreg, stackoffs) \
+ (MK_FLD(INSTR_OP, OP_3) | \
+ MK_FLD(INSTR_RD, dreg) | \
+ MK_FLD(INSTR_OP3, OP3_LDX) | \
+ MK_FLD(INSTR_RS1, R_SP) | \
+ MK_FLD(INSTR_I , 1 ) | \
+ MK_FLD(INSTR_SIMM13, stackoffs))
+
+
+// Move a value between two registers
+#define MK_MOV_R_R(dreg, sreg) \
+ (MK_FLD(INSTR_OP, OP_2) | \
+ MK_FLD(INSTR_RD, dreg) | \
+ MK_FLD(INSTR_OP3, OP3_MOVcc) | \
+ MK_FLD(INSTR_RS2, sreg) | \
+ MK_FLD(INSTR_I , 0 ) | \
+ MK_FLD(INSTR_COND_L, COND_BA) | \
+ MK_FLD(INSTR_CC2 , 1 ) | \
+ MK_FLD(INSTR_MOV_CC1 , 1 ) | \
+ MK_FLD(INSTR_MOV_CC0, 0 ))
+
+// Store a word in sreg to O6/SP + stackoffs
+#define MK_STX_STACK(sreg, stackoffs) \
+ (MK_FLD(INSTR_OP, OP_3) | \
+ MK_FLD(INSTR_RD, sreg) | \
+ MK_FLD(INSTR_OP3, OP3_STX) | \
+ MK_FLD(INSTR_RS1, R_SP) | \
+ MK_FLD(INSTR_I , 1 ) | \
+ MK_FLD(INSTR_SIMM13, stackoffs))
+
+// Add a constant to a register
+#define MK_ADD_R_I(dreg, sreg, imm) \
+ (MK_FLD(INSTR_OP, OP_2) | \
+ MK_FLD(INSTR_RD, dreg) | \
+ MK_FLD(INSTR_RS1, sreg) | \
+ MK_FLD(INSTR_SIMM13, imm) | \
+ MK_FLD(INSTR_I, 1) | \
+ MK_FLD(INSTR_OP3, OP3_ADD))
+
+
+
Index: llvm/lib/Reoptimizer/BinInterface/analyze.cpp
diff -u llvm/lib/Reoptimizer/BinInterface/analyze.cpp:1.4 llvm/lib/Reoptimizer/BinInterface/analyze.cpp:1.5
--- llvm/lib/Reoptimizer/BinInterface/analyze.cpp:1.4 Wed Nov 27 20:19:49 2002
+++ llvm/lib/Reoptimizer/BinInterface/analyze.cpp Sat Dec 14 19:30:54 2002
@@ -17,7 +17,7 @@
#include <stdio.h>
#include <stdlib.h>
-#include "sparc9.hp" // SPARC 9 opcode and field definitions
+#include "sparc9.h" // SPARC 9 opcode and field definitions
#include "bitmath.h"
#include "analyze.h" // API library
#include <assert.h>
@@ -138,6 +138,22 @@
return IF_RD | IF_RS1 | IF_RS2 | IF_WCC | IF_RCC | IF_W_RD | IF_R_RS1 | IF_R_RS2;
else
return IF_RD | IF_RS1 | IF_WCC | IF_RCC | IF_W_RD | IF_R_RS1;
+
+ case OP3_MOVcc:
+ if (RD_FLD(instr, INSTR_I) == 0)
+ {
+ if (RD_FLD(instr, INSTR_COND_L)==COND_BA)
+ return IF_RD | IF_RS2 | IF_W_RD | IF_R_RS2;
+ else
+ return IF_RD | IF_RS2 | IF_W_RD | IF_R_RS2 | IF_RCC;
+ }
+ else
+ {
+ if (RD_FLD(instr, INSTR_COND_L)==COND_BA)
+ return IF_RD | IF_W_RD;
+ else
+ return IF_RD | IF_W_RD | IF_RCC;
+ }
default:
printf("Unknown:OP=0b10 OP3 = 0x%04X\n", RD_FLD(instr, INSTR_OP3));
@@ -225,14 +241,14 @@
// they are cancel read or write flags on that field
if (flags & IF_RS1)
- if (!RD_FLD(instr, INSTR_RS1))
+ if ((1 << RD_FLD(instr, INSTR_RS1)) & RM_IGNORE)
flags &= ~IF_R_RS1;
if (flags & IF_RS2)
- if (!RD_FLD(instr, INSTR_RS2))
+ if ((1 << RD_FLD(instr, INSTR_RS2)) & RM_IGNORE)
flags &= ~IF_R_RS2;
if (flags & IF_RD)
- if (!RD_FLD(instr, INSTR_RD))
+ if ((1 << RD_FLD(instr, INSTR_RD)) & RM_IGNORE)
flags &= ~(IF_R_RD | IF_W_RD);
return flags;
@@ -322,3 +338,4 @@
}
}
}
+
Index: llvm/lib/Reoptimizer/BinInterface/analyze.h
diff -u llvm/lib/Reoptimizer/BinInterface/analyze.h:1.3 llvm/lib/Reoptimizer/BinInterface/analyze.h:1.4
--- llvm/lib/Reoptimizer/BinInterface/analyze.h:1.3 Wed Nov 27 20:19:50 2002
+++ llvm/lib/Reoptimizer/BinInterface/analyze.h Sat Dec 14 19:31:33 2002
@@ -13,6 +13,7 @@
#ifndef __ANALYZE__
#define __ANALYZE__
+#include "sparcpriv.h"
#define IF_RS1 0x001 // Presence of RS1 field in instruction
#define IF_RS2 0x002 // Presence of RS2 field in instruction
@@ -29,6 +30,9 @@
// flags along side these when we store them in the
// SSA form. This is the first 'user' flag available
+
+
+
/*
Important NOTE!
@@ -50,4 +54,5 @@
unsigned sparc_setbrdest(unsigned instr, signed reladdr);
signed sparc_getbrdest(unsigned instr);
-#endif
\ No newline at end of file
+#endif
+
Index: llvm/lib/Reoptimizer/BinInterface/bitmath.h
diff -u llvm/lib/Reoptimizer/BinInterface/bitmath.h:1.3 llvm/lib/Reoptimizer/BinInterface/bitmath.h:1.4
--- llvm/lib/Reoptimizer/BinInterface/bitmath.h:1.3 Wed Nov 27 20:19:51 2002
+++ llvm/lib/Reoptimizer/BinInterface/bitmath.h Sat Dec 14 19:31:33 2002
@@ -2,6 +2,16 @@
//
// High Performance Bit Utility Functions
//
+// Contains
+// * Routines for rounding to specific powers of 2
+// * Bitfield access macros
+// * Sign extend macro
+// * Extract bitmask of lowest bit set
+// * Fast bit-set counting for sparse and dense bitfields
+// * Fast modulo 3 test and remainder calculation
+// * Fast parity calculation
+// * Fast log2 (for 32-bit numbers ONLY!)
+//
//
// 2002 Cameron Buschardt
//*****************************************************************************
@@ -10,26 +20,34 @@
#define __BITMATH_H__
//*********************************
+// Misc functions
+//*********************************
+#define P2KM1(k) ((1 << (k))-1) // (2 ^ K) - 1
+#define ROUNDUP_P2(x, k) ((x+P2KM1(k)) &~ P2KM1(k))
+#define ROUNDUP32(x) ROUNDUP_P2(x,5) // round up to nearest mult of 32
+
+
+//*********************************
// Bitfield manipulation Macros
//*********************************
#define FLD_UPPER(FLD_DEF) (1 ? FLD_DEF)
#define FLD_LOWER(FLD_DEF) (0 ? FLD_DEF)
-#define MASKBELOW(V) ((1 << V) - 1)
-#define MASKEQBELOW(V) ((1 << V) | MASKBELOW(V)) //masks off everything ABOVE
-#define RD_FLD(x, FLD) ((x & MASKEQBELOW(FLD_UPPER(FLD))) >> FLD_LOWER(FLD))
-#define MK_FLD(FLD, val) ((val << FLD_LOWER(FLD)) & MASKEQBELOW(FLD_UPPER(FLD)))
-#define MASK_FLD(FLD) (MASKEQBELOW(FLD_UPPER(FLD)) & ~MASKBELOW(FLD_LOWER(FLD)))
-#define RM_FLD(FLD, val) (val & ~(MASK_FLD(FLD)))
+#define MASKBELOW(V) ((1 << V) - 1)
+#define MASKEQBELOW(V) ((1 << V) | MASKBELOW(V)) //masks off everything ABOVE
+#define RD_FLD(x, FLD) ((x & MASKEQBELOW(FLD_UPPER(FLD))) >> FLD_LOWER(FLD))
+#define MK_FLD(FLD, val) ((val << FLD_LOWER(FLD)) & MASKEQBELOW(FLD_UPPER(FLD)))
+#define MASK_FLD(FLD) (MASKEQBELOW(FLD_UPPER(FLD)) & ~MASKBELOW(FLD_LOWER(FLD)))
+#define RM_FLD(FLD, val) (val & ~(MASK_FLD(FLD)))
//**********************************
// Portable sign extend macros
//**********************************
-#define SIGN_EXTEND13(x) (x & 0x1000 ? -(-x & 0x1FFF): x)
+#define SIGN_EXTEND13(x) (x & 0x1000 ? -(-x & 0x1FFF): x)
#define SIGN_EXTEND(x, bits) (x & (1 << (bits-1)) ? -(-x & ((1 << bits)-1)):x)
-#define IS_POWER_2(x) !(x & (x-1))
-#define LOWEST_BIT(x) x & ~(x & (x-1))
-#define UPPER_BITS(x) (x & (x-1))
+#define IS_POWER_2(x) !(x & (x-1))
+#define LOWEST_BIT(x) (x & ~(x & (x-1)))
+#define UPPER_BITS(x) (x & (x-1))
// Good if expected number of bits set < 4
static int countbits_sparse(unsigned m) //VALIDATED
@@ -85,7 +103,11 @@
return w & 1;
}
-
+//
+// Note: users of this function may depend on the fact
+// that log2(0) will return 0. Since it is
+// undefined I have chosen this value.
+//
static int log2(unsigned w) //VALIDATED
{
int n = 0;
@@ -107,9 +129,10 @@
}
w <<= 1;
- return ((0xFFFFAA50 >> w) & 3)+n;
+ return ((0xFFFFAA50 >> w) & 3)+n; // this is a LUT
}
#endif
+
Index: llvm/lib/Reoptimizer/BinInterface/fvector.h
diff -u llvm/lib/Reoptimizer/BinInterface/fvector.h:1.3 llvm/lib/Reoptimizer/BinInterface/fvector.h:1.4
--- llvm/lib/Reoptimizer/BinInterface/fvector.h:1.3 Wed Nov 27 20:19:51 2002
+++ llvm/lib/Reoptimizer/BinInterface/fvector.h Sat Dec 14 19:31:40 2002
@@ -21,8 +21,10 @@
T * v_begin;
T * v_end;
T * v_capacity;
- StackAllocator * alloc;
+ Allocator * alloc;
+ // make sure we have MEMORY up to that element
+ // does not construct those positions
void validate(T * pos)
{
assert(alloc);
@@ -45,6 +47,23 @@
}
fvector(const fvector &) {}
+ fvector & operator = (const fvector &) {}
+ void destroy(T * b, T * e)
+ {
+ while (b!=e)
+ {
+ b->~T();
+ b++;
+ }
+ }
+ void construct(T * b, T * e)
+ {
+ while (b!=e)
+ {
+ new (b) T();
+ b++;
+ }
+ }
public:
typedef T * iterator;
@@ -52,14 +71,20 @@
iterator end() { return v_end; }
void clear()
{
+ assert(this);
+ destroy(v_begin, v_end);
if (v_begin)
alloc->free(v_begin);
v_begin = v_capacity = v_end = NULL;
}
- unsigned size() { return v_end - v_begin; }
+ unsigned size()
+ {
+ assert(this);
+ return v_end - v_begin;
+ }
- fvector(StackAllocator * a)
+ fvector(Allocator * a)
{
v_begin = v_end = v_capacity = NULL;
alloc = a;
@@ -72,7 +97,7 @@
}
- void setallocator(StackAllocator * a)
+ void setallocator(Allocator * a)
{
assert(!alloc);
alloc = a;
@@ -82,29 +107,43 @@
{
if (v_begin)
return;
- v_begin = (T*)alloc->alloc(sizeof(T) * v);
+ v_begin = (T*)alloc->alloc(sizeof(T) * v);
v_end = v_begin;
v_capacity = v_begin + v;
}
void push_back(const T & e) {
- validate(v_end+1);
- *v_end++ = e;
+ assert(this);
+ validate(v_end+1);
+ new (v_end) T(e);
+ v_end++;
}
void inc(unsigned amt) // increase size by this amt
{
validate(v_end + amt);
+ construct(v_end, v_end+amt);
v_end += amt;
}
void resize(unsigned amt)
{
- validate(v_begin + amt);
- v_end = v_begin + amt;
+ if ((v_begin+amt) < v_end)
+ {
+ // got shorter
+ destroy((v_begin+amt), v_end);
+
+ }
+ else
+ {
+ // got longer
+ validate( v_begin+amt);
+ construct(v_end, v_begin+amt);
+ }
+ v_end = v_begin+amt;
}
-
- T& operator[] (unsigned n) { return v_begin[n]; }
+ T& operator[] (unsigned n) { printf("write 0x%08X\n", v_begin+n);
+ return v_begin[n]; }
const T & operator[] (unsigned n) const { return v_begin[n]; }
@@ -112,3 +151,4 @@
#endif
+
Index: llvm/lib/Reoptimizer/BinInterface/salloc.cpp
diff -u llvm/lib/Reoptimizer/BinInterface/salloc.cpp:1.1 llvm/lib/Reoptimizer/BinInterface/salloc.cpp:1.2
--- llvm/lib/Reoptimizer/BinInterface/salloc.cpp:1.1 Wed Nov 27 20:19:55 2002
+++ llvm/lib/Reoptimizer/BinInterface/salloc.cpp Sat Dec 14 19:31:41 2002
@@ -6,17 +6,18 @@
// 2002 Cameron Buschardt
//*****************************************************************************
+#include <memory.h>
#include "salloc.h"
-#include <assert.h>
+#include "bitmath.h"
#include <stdio.h>
#include <stdlib.h>
-#include "machine.h"
+#include <assert.h>
// work around incompetant compiler
#define PRINTALLOC
+// look up the size of a block by address
#define BSIZE(x) *((unsigned *)((unsigned char *)x - sizeof (unsigned)))
-extern "C" void memcpy(void *, void *, unsigned);
void * StackAllocator::alloc(unsigned size)
{
@@ -45,7 +46,7 @@
unsigned oldsize=BSIZE(block);
memcpy(r, block, oldsize);
PRINTALLOC("Resize(%08X, %d) = new block: %08X \n", block, newsize, r);
-
+ free(block);
return r;
}
else
@@ -84,20 +85,19 @@
StackAllocator::StackAllocator(unsigned size)
{
// round size up to next multiple of CACHE_LINE
- size+= ((1 << MACHINE_CACHELINE)-1);
- size&= ~((1 << MACHINE_CACHELINE)-1);
-
- begin = new unsigned char[size];
+ size=ROUNDUP32(size);
+ begin = (unsigned char *)malloc(size);
end = begin + size;
top = begin;
}
StackAllocator::~StackAllocator()
{
- delete begin;
+ free(begin);
}
void StackAllocator::print()
{
printf("Stack alloc : %g kbytes used of %g kbytes\n", double(top-begin)/1000, double(end-begin)/1000);
-}
\ No newline at end of file
+}
+
Index: llvm/lib/Reoptimizer/BinInterface/salloc.h
diff -u llvm/lib/Reoptimizer/BinInterface/salloc.h:1.1 llvm/lib/Reoptimizer/BinInterface/salloc.h:1.2
--- llvm/lib/Reoptimizer/BinInterface/salloc.h:1.1 Wed Nov 27 20:19:55 2002
+++ llvm/lib/Reoptimizer/BinInterface/salloc.h Sat Dec 14 19:31:41 2002
@@ -3,11 +3,15 @@
//
// Definitions of Base Allocator class and Stack allocator
//
+//
+//
// 2002 Cameron Buschardt
//*****************************************************************************
#ifndef __SALLOC_H__
#define __SALLOC_H__
+#include <memory.h>
+#include <stdlib.h>
//*********************************
// Generic Allocator
@@ -22,6 +26,8 @@
virtual void*resize(void * block , unsigned newsize) = 0;
};
+
+
//*********************************
// Stack Allocator
//*********************************
@@ -43,4 +49,5 @@
};
-#endif
\ No newline at end of file
+#endif
+
Index: llvm/lib/Reoptimizer/BinInterface/sparcbin.cpp
diff -u llvm/lib/Reoptimizer/BinInterface/sparcbin.cpp:1.1 llvm/lib/Reoptimizer/BinInterface/sparcbin.cpp:1.2
--- llvm/lib/Reoptimizer/BinInterface/sparcbin.cpp:1.1 Wed Nov 27 20:20:11 2002
+++ llvm/lib/Reoptimizer/BinInterface/sparcbin.cpp Sat Dec 14 19:32:10 2002
@@ -23,10 +23,10 @@
#include "fvector.h" // fast vector (sits on stack allocator)
#include "analyze.h" // SPARC analysis library (gets flag masks for instrs)
#include "sparcbin.h" // Prototype for this class
-#include "machine.h" // machine constants for cache optimizations
+#include "sparcpriv.h" // Private definitions#include "machine.h" // machine constants for cache optimizations
#include "sparcdis.h" // prototype for sparc disassembler
#include "bitmath.h" // header of optimized binary math routines
-#include "sparc9.hp" // SPARC 9 opcode definitions
+#include "sparc9.h" // SPARC 9 opcode definitions
#include <vector>
using std::pair;
@@ -38,17 +38,6 @@
#include <new>
-#define IF_ALUOP (IF_USR << 1)
-#define IF_PHI (IF_USR << 2)
-#define IF_NODELIVEIN (IF_USR << 3) // instr field is register to bind to
-#define IF_NODELIVEOUT (IF_USR << 4) // instr field is register dest.. genrs1 is source value
-#define IF_LIVEOUT (IF_USR << 5) // is a normal instr liveout
-#define IF_BRINTERNAL (IF_USR << 6) // is this an INTERNAL branch if so use ibranch
-
-
-// a call instruction will spill all the outgoing registers O0->O7 (R8-R15)
-#define R_CALLSPILLS 0x0000FF00
-#define R_ALLOCREGS 0xFFFFBFFE // allocate all regs except R0(G0), O6(R14)(SP)
//
@@ -65,27 +54,6 @@
-//
-// Register state definition used during selection process
-//
-
-//
-// The usecount and current register any value is in.
-// Note! reg can either be a stack location (negative) or
-// a register index (positive)
-// If reg < 0 then then stackidx = ~reg
-//
-
-struct SSATerm
-{
- unsigned uses;
- unsigned lastuse; //end of live range
- int reg; //negative denotes stack location
-
-
- SSATerm() : uses(0), reg(0) {}
-};
-
@@ -97,483 +65,30 @@
//
-struct vreginfo
-{
- unsigned uses;
- unsigned lastuse;
- int mreg;
-};
-// Register field. VERY similar to a bitvector
-// with a few minor changes
-
-struct regmask
-{
- fvector<unsigned> freemap;
-
-
- // Construct freemap, initially mark everyone free
- regmask(StackAllocator * a, unsigned maxregs)
- : freemap(a)
- {
- // make sure unsigned it at least 32-bits
- assert(countbits_dense(~unsigned(0))>=32);
-
- // calculate size of freemap
- freemap.inc( (maxregs + 31) >> 5 ); //round up to nearest 32
- for (int k = 0; k < freemap.size(); k++)
- freemap[k] = ~0;
- }
-
- // returns 0 on failure
- unsigned allocreg() // allocate ANY register
- {
- for (int k = 0; k<freemap.size(); k++)
- if (freemap[k]) // Are there any bits marked free?
- {
- unsigned mask = LOWEST_BIT(freemap[k]);
- freemap[k] &= ~mask; // mark it used
- // printf("grab reg %d\n",log2(mask)+(k << 5));
- return log2(mask)+(k << 5); // fast log2
- }
- return 0;
- }
-
- // returns 0 on failure
- unsigned allocreg32() // allocate register from first 32 only
- {
- unsigned mask = LOWEST_BIT(freemap[0]); // on fail this will be 0
- freemap[0] &= ~mask; // on fail this will be a nop
- return log2(mask); // log2(0) == log2(1) == 0 (in this implementation!)
- // I fully realize log2(0) is undefined =p
- }
-
- void freereg(unsigned idx)
- {
- //printf("free reg %d\n", idx);
- freemap[idx >> 5] |= 1 << (idx & 31); // mark it free
- }
-
- void grabreg(unsigned idx)
- {
- freemap[idx >> 5] &= ~(1 << (idx & 31)); // grab it
- }
-
- void set32(unsigned mask)
- {
- freemap[0] = mask;
- }
-
- // count how many are free in the lowest 32.
- unsigned count32()
- {
- return countbits_dense(freemap[0]);
- }
-
- unsigned isreg32()
- {
- return freemap[0];
- }
-};
unsigned BinInterface::emit(unsigned char * out)
{
+ int spillreg;
+ int memspills[32];
+ unsigned touched, stack;
// Table to look up virtual register for SSA node
// this is done to condense PHI node references
- fvector<unsigned> ssa_to_vreg(&alloca);
- fvector<vreginfo> vregs(&alloca); // index 0 never assigned
+ regalloc regs(alloca);
+
- select(ssa_to_vreg, vregs); // condense phi nodes and calculate
+ select(regs); // condense phi nodes and calculate
// live ranges
- return emit_gen(out, ssa_to_vreg, vregs); // do linear scan register allocation
+ return emit_gen(out, regs); // do linear scan register allocation
// interleaved with code generation
}
-int BinInterface::spillreg(int spillloc, unsigned * & out, fvector<vreginfo> & vregs, regmask & freeregs, unsigned hwregs[32])
-{
-
- // Select a live range to spill
- unsigned min_cnt = 0xFFFFFFFF;
- unsigned min_idx = 0;
-
- for (int j = 0; j < 32; j++)
- {
- if (!hwregs[j])
- continue;
-
- vreginfo & v = vregs[hwregs[j]];
- if (v.uses < min_cnt)
- {
- min_cnt = v.uses;
- min_idx = j;
- }
- }
- // Spill the live range to the location we allocated
- vregs[hwregs[min_idx]].mreg = spillloc; // update map
-
- // spill the live-range
- *out++=(MK_STX_STACK(min_idx, 8*(spillloc - 32)));
-
- return min_idx;
-}
-
-//
-// Spill load
-// - loads value into register (performing spill if needed)
-// - validates use constraints and identifies the end of a live-range
-//
-int BinInterface::spill_load(int useid, int id, unsigned * & out, fvector<vreginfo> & vregs, regmask & freeregs, unsigned hwregs[32])
-{
- int rs1 = vregs[id].mreg;
-
- if (rs1 >= 32) // not a hardware register?
- {
- // First try allocating a candindate register
- int sreg = freeregs.allocreg();
-
- // if sreg wasn't a hardware register spill something into it
- // and return the register we spilled
- if (sreg >= 32)
- sreg = spillreg(sreg, out, vregs, freeregs, hwregs);
-
- // update the virtual register map
- hwregs[sreg] = id;
- vregs[id].mreg = sreg;
- freeregs.freereg(rs1); // free the old area since we're loading it
-
- // perform a spill load on the parameters
- *out++=(MK_LDX_STACK(sreg, 8*(rs1-32)));
-
-
- return sreg;
- }
- else
- return rs1; //it was already in a register
-}
-
-unsigned BinInterface::emit_gen(unsigned char * cde, fvector<unsigned> &ssa_to_vreg, fvector<vreginfo> & vregs)
-{
- unsigned * out = (unsigned *) cde;
-
- fvector<pair<unsigned *, unsigned> > fwdbranch(&alloca); // pairs of instruction addrs +destination section #'s
- fvector<unsigned *> secaddr(&alloca); // address of section
-
- secaddr.inc(sections.size());
-
- // register allocation state
- regmask freeregs(&alloca,itable.size()); // includes stack positions
- unsigned hwregs[32]; // vreg index in that register
- freeregs.set32(R_ALLOCREGS); // mark candidate registers free
-
- for (int s = 0; s< 32; s++)
- hwregs[s] = 0;
-
- // Allocate registers that are marked as live in values
- for (int p = 0; p<livein.size(); p++)
- {
- // Mark down the register assignment in vreg structure
- int mreg = itable[livein[p]]->livein.reg;
- vregs[ ssa_to_vreg[livein[p]] ].mreg = mreg;
-
- // Mark that register not free
- freeregs.grabreg(mreg);
- hwregs[mreg] = ssa_to_vreg[livein[p]];
- }
-
- // Iterate across instructions
- for (int s=0;s<sections.size();s++)
- {
- secaddr[s] = out; // mark down section start address for patching
- // jump instructions
- for (int i = begin(s); i!=end(s); i=next(i))
- {
- // Find what registers this instruction depends on.
- int rs1; // this register will contain the rs1 value
- int rs2; // this register will contain the rs2 value
- int rd; // this register will contain the rd value
-
- instruction * instr = itable[i];
- unsigned flags = instr->flags;
-
- if (flags & IF_NODELIVEOUT)
- {
- // load the value into a register.
- int gen = ssa_to_vreg[instr->liveout.gen];
- int sreg = vregs[gen].mreg;
- int dreg = instr->liveout.reg;
-
- assert(dreg < 32);
-
- if (sreg==dreg) //we don't need to do a transfer
- continue;
-
- // spill whatever is in DREG
- if (hwregs[dreg])
- {
- int spillloc = freeregs.allocreg();
- // Spill the live range to the location we allocated
- if (spillloc < 32)
- {
- hwregs[spillloc] = hwregs[dreg];
- *out++=(MK_MOV_R_R(spillloc, dreg));
- }
- else
- {
- *out++=(MK_STX_STACK(dreg, 8*(spillloc - 32)));
- }
- vregs[hwregs[dreg]].mreg = spillloc; // update map
-
- }
-
- // use dreg
- if (sreg >= 32) // stack variable?
- {
- *out++=(MK_LDX_STACK(dreg, 8*(sreg - 32)));
- }
- else
- {
- *out++=(MK_MOV_R_R(dreg,sreg));
- }
-
- // we don't want to accidentally spill this register.
- // make sure it is allocated and mark it no use
-
- hwregs[dreg] = 0; // off-limits
- freeregs.grabreg(dreg);
- continue;
- }
-
- // make sure this is ACTUALLY an instruction and not a phi node
- if (! (flags & (IF_ALUOP | IF_BR)))
- continue;
-
- unsigned spilled = 0; // a mask of the registers
- // that were spilled for the parameters
- // this is here so that when we spill
- // a live range that is in a reigster -
- // we don't accidentally spill one of the OTHER
- // parameters
-
- // load parameters of instruction
- if (flags & IF_R_RS1)
- {
- int id = ssa_to_vreg[instr->alu.genrs1];
- // verify value is in register / return register
- rs1 = spill_load(i,id, out, vregs, freeregs, hwregs);
-
- }
-
- if (flags & IF_R_RS2)
- {
- int id = ssa_to_vreg[instr->alu.genrs2];
- rs2 = spill_load(i,id, out, vregs, freeregs, hwregs);
- }
-
- if (flags & IF_R_RD)
- {
- int id = ssa_to_vreg[instr->alu.genrd];
- rd = spill_load(i,id, out, vregs, freeregs, hwregs);
- }
-
-
- //
- // Branch instructions must have their target fixed up
- // (note that the next instruction emitted is guaranteed
- // to be the actual instruction and not a spill fixup)
- if (flags & IF_BR)
- {
- if (flags & IF_BRINTERNAL)
- {
- // we need to fix up destination. If this is a backward branch no problem
- // forward branches we store a backtable FIXME
- if (instr->ibranch.dest <= s)
- {
- unsigned rel = secaddr[instr->ibranch.dest] - out;
- instr->instr = sparc_setbrdest(instr->instr,rel);
- }
- else
- fwdbranch.push_back(pair<unsigned *, unsigned>(out, instr->ibranch.dest));
- }
- else
- {
- // do absolute jump
- unsigned rel = instr->ebranch.dest - out;
- instr->instr = sparc_setbrdest(instr->instr,rel);
- }
- }
-
-
- // parameters of instruction have been loaded. Figure out what register we're going to write
- // destination to
- unsigned ins = instr->instr;
- // mask off and replace rs1
- if (flags & IF_R_RS1)
- {
- ins = RM_FLD(INSTR_RS1, ins) | MK_FLD(INSTR_RS1, rs1);
- int vid = ssa_to_vreg[instr->alu.genrs1];
- if (vregs[vid].lastuse == i)
- {
- freeregs.freereg(vregs[vid].mreg);
- hwregs[rs1] = 0;
- }
- }
-
- if (flags & IF_R_RS2)
- {
- ins = RM_FLD(INSTR_RS2, ins) | MK_FLD(INSTR_RS2, rs2);
- int vid = ssa_to_vreg[instr->alu.genrs2];
-
- if (vregs[vid].lastuse == i)
- {
- freeregs.freereg(vregs[vid].mreg);
- hwregs[rs2] = 0;
- }
- }
-
- if (flags & IF_R_RD)
- {
- ins = RM_FLD(INSTR_RD, ins) | MK_FLD(INSTR_RD, rd);
- int vid = ssa_to_vreg[instr->alu.genrd];
- if (vregs[vid].lastuse == i)
- {
- freeregs.freereg(vregs[vid].mreg);
- hwregs[rd] = 0;
- }
- }
-
- if (flags & IF_W_RD)
- {
- int id = ssa_to_vreg[i];
-
- // We need to generate and store a result. We should check to see
- // if any registers are currently 'free'. If not we must spill one.
-
- int dreg = freeregs.allocreg();
-
- if (dreg >= 32) // got a stack location? spill something to it
- dreg = spillreg(dreg, out, vregs, freeregs, hwregs);
-
- hwregs[dreg] = i;
-
- // emit the instruction using this register as the destination
- ins = RM_FLD(INSTR_RD, ins) | MK_FLD(INSTR_RD, dreg);
- *out++=(ins);
-
- // modify the map to reflect this register as containing this SSA value
- vregs[id].mreg = dreg;
-
- }
- else
- *out++=(ins); // no dreg? just emit it
- }
- }
-
- //
- // Handle forward branches.
- //
- for(int t = 0; t<fwdbranch.size(); t++)
- {
- pair<unsigned *, unsigned> & i = fwdbranch[t];
-
- unsigned rel = secaddr[i.second] - out;
- *i.first = sparc_setbrdest(*i.first,rel);
- }
-
- return out- ((unsigned *)cde);
-}
-void BinInterface::select(fvector<unsigned> &ssa_to_vreg,fvector<vreginfo> &vregs)
-{
- int free_vreg = 1 ; // first free
-
- // Mark everyone as having no register assigned
- ssa_to_vreg.inc(itable.size());
- for (int k = 0; k<ssa_to_vreg.size(); k++)
- ssa_to_vreg[k] = 0;
-
-
- // Condense PHI nodes
- for (int s=0;s<sections.size();s++)
- for (int i = begin(s); i!=end(s); i=next(i))
- {
- instruction * instr = itable[i];
- unsigned flags = instr->flags;
-
- if (flags & IF_PHI)
- {
- for (int p=0; p< instr->phi.params->size(); p++)
- {
- int id = (*instr->phi.params)[p];
- ssa_to_vreg[id] = free_vreg;
- }
- ssa_to_vreg[i] = free_vreg;
- free_vreg++;
- }
- }
-
- // size the vreg structures and initialize
- vregs.inc(itable.size());
- for (int p = 0 ; p < free_vreg; p++)
- vregs[p].uses = vregs[p].lastuse = vregs[p].mreg = 0;
-
-
- // Assign Vregs to non-phi parameters. Calculate usage information
- // for ALL virtual registers.
- for (int s=0;s<sections.size();s++)
- for (int i = begin(s); i!=end(s); i=next(i))
- {
- instruction * instr = itable[i];
- unsigned flags = instr->flags;
-
- if (!ssa_to_vreg[i]) //not got a vreg yet?
- {
- // allocate one
- ssa_to_vreg[i] = free_vreg;
- vregs.inc(1);
- vregs[free_vreg].uses = vregs[free_vreg].lastuse = vregs[free_vreg].mreg = 0;
- free_vreg++;
- }
-
- if (flags & IF_NODELIVEOUT)
- {
- vregs[ ssa_to_vreg[instr->liveout.gen] ].uses++;
- vregs[ ssa_to_vreg[instr->liveout.gen] ].lastuse = i;
- continue;
- }
-
- // note since PHI nodes have been collapsed
- // through the vreg assignment. we don't need to process them! =p
- // Livein nodes are also skipped
- if (flags & (IF_ALUOP | IF_BR))
- {
- if (flags & IF_R_RS1) // do we read from RS1?
- {
- int id = ssa_to_vreg[instr->alu.genrs1];
- vregs[id].uses++;
- vregs[id].lastuse = i;
- }
- if (flags & IF_R_RS2) // do we read from RS2?
- {
- int id = ssa_to_vreg[instr->alu.genrs2];
- vregs[id].uses++;
- vregs[id].lastuse = i;
- }
- if (flags & IF_R_RD) // do we read from RD?
- {
- int id = ssa_to_vreg[instr->alu.genrd];
- vregs[id].uses++;
- vregs[id].lastuse = i;
- }
- }
- }
-}
-
-
@@ -585,222 +100,20 @@
instruction * BinInterface::allocphi()
{
- instruction * phi = (instruction *)alloca.alloc(sizeof(instruction));
+ instruction * phi = (instruction *)alloca->alloc(sizeof(instruction));
phi->flags = IF_PHI;
phi->next = phi->prev = phi->self = itable.size();
itable.push_back(phi);
// allocate memory for fvector AND call constructor
- phi->phi.params = (fvector<unsigned> *)alloca.alloc(sizeof(fvector<unsigned>));
- new ((void *)phi->phi.params) fvector<unsigned>(&alloca);
+ phi->phi.params = (fvector<unsigned> *)alloca->alloc(sizeof(fvector<unsigned>));
+ new ((void *)phi->phi.params) fvector<unsigned>(alloca);
return phi;
}
-void BinInterface::process_markgen(unsigned s, unsigned map[32],fvector<unsigned[32]> & regmaps)
-{
- // iterate all instructions in this section
- for (int i = begin(s); i!=end(s); )
- {
- // look at instruction
- instruction * instr = itable[i];
- unsigned flags = instr->flags;
-
- // what uses?
- if (flags & IF_R_RS1)
- {
- int rs1 = RD_FLD(instr->instr, INSTR_RS1);
- if (!map[rs1])
- // oops. we just made a reference to an incoming value. Instantiate
- map[rs1] = allocnodelivein(sections[0],rs1);
-
- instr->alu.genrs1 = map[rs1];
- }
-
- if (flags & IF_R_RS2)
- {
- int rs2 = RD_FLD(instr->instr, INSTR_RS2);
- if (!map[rs2])
- map[rs2] = allocnodelivein(sections[0],rs2);
- instr->alu.genrs2 = map[rs2];
- }
-
- if (flags & IF_R_RD)
- {
- int rd = RD_FLD(instr->instr, INSTR_RD);
- if (!map[rd])
- map[rd] = allocnodelivein(sections[0], rd);
- instr->alu.genrd = map[rd];
- }
-
- // does he write to a register?
- if (flags & IF_W_RD)
- map[RD_FLD(instr->instr, INSTR_RD)] = i;
- else if (flags & IF_PHI)
- map[instr->instr] = instr->self; // use phi node for reg val
-
- // advance
- i = instr->next;
-
- }
-}
-
-
-void BinInterface::process_section(unsigned s, unsigned map[32],fvector<unsigned[32]> & regmaps)
-{
- // We inherit map from parent (p->t->e) -- FIX HANDLING OF MULTIPLE EPILOGS
- for (int v=0;v<32;v++)
- regmaps[s][v] = map[v];
-
- // iterate all instructions in this section
- for (int i = begin(s); i!=end(s); )
- {
- // look at instruction
- instruction * instr = itable[i];
- unsigned flags = instr->flags;
-
- // is the instruction a branch?
- if (flags & IF_BRINTERNAL)
- {
-
- // follow the branch and MERGE the tables.
- int brdest = instr->ibranch.dest;
-
- for (int q=0;q<32;q++)
- if (!regmaps[brdest][q])
- regmaps[brdest][q] = map[q];
- else if (regmaps[brdest][q]!=map[q])
- {
- // we need a phi node - or we need to append to one
- instruction * d = itable[regmaps[brdest][q]];
- if (d->flags & IF_PHI)
- {
- if (!map[q])
- map[q] = allocnodelivein(s,q); //must have been livein
- d->phi.params->push_back(map[q]); // append to a phi node
- }
- else
- {
- // create a phi node
- instruction * phi = allocphi();
-
- // Live in check
- if (!regmaps[brdest][q])
- regmaps[brdest][q] = allocnodelivein(s,q);
-
- phi->phi.params->push_back(regmaps[brdest][q]);
-
- // live in check
- if (!map[q])
- map[q] = allocnodelivein(s,q);
-
- phi->phi.params->push_back(map[q]);
-
- // link in the phi node and update both maps
- insert_instr(sections[s], phi);
- map[q] = phi->self;
- regmaps[brdest][q] = phi->self;
- phi->instr = q; // the register it applies to
- }
- }
-
- }
-
- // does he write to a register?
- if (flags & IF_W_RD)
- map[RD_FLD(instr->instr, INSTR_RD)] = i;
-
- i = instr->next;
- }
-}
-
-
-void BinInterface::reduce()
-{
- fvector<unsigned[32]> regmaps(&alloca);
-
- regmaps.resize(sections.size());
-
-
- unsigned map[32],mapepi[32]; // current map
-
-
- for (int i = 0; i < 32; i++)
- map[i] = 0; // instruction ID #0 is a loop header.
- // there is no way a register could
- // be generated by it. So we use 0
- // as a NULL marker
-
- // Clear header maps
- for (int s=0;s<sections.size();s++)
- for (int p=0;p<32;p++)
- regmaps[s][p] = 0;
-
- int scns = sections.size();
-
-
- process_section(SECTION_PROLOG, map, regmaps);
- process_section(SECTION_TRACE, map, regmaps);
-
- // iterate across sections
- for (int s=SECTION_TRACE+1;s<sections.size();s++)
- {
- for (int i = 0; i < 32; i++)
- mapepi[i] = map[i];
- process_section(s,mapepi, regmaps);
- }
-
- //
- // Phi nodes have been calculated - and most importantly placed in respective positions
- // phi->instr holds the register number in question
- //
- // Execute program in order and connect phi nodes
- //
-
- // clear the map
- for (int v=0;v<32;v++)
- map[v] = 0;
-
- process_markgen(SECTION_PROLOG, map, regmaps);
- process_markgen(SECTION_TRACE , map, regmaps);
-
-
- for (int s=SECTION_TRACE+1;s<sections.size();s++)
- {
- for (int i = 0; i < 32; i++)
- mapepi[i] = map[i];
- process_markgen(s, mapepi,regmaps);
-
- // mapepi contains the register map for this epilog. Check if any values reaching in registers
- // were marked liveout. If they are insert a NODELIVEOUT instruction at the end
-
- for (int i=0;i<32; i++)
- {
- instruction * instr = itable[mapepi[i]];
- if (instr->flags & IF_PHI)
- {
- // if any of the PHI parameters are marked live out,
- // the phi node itself becomes liveout.
- unsigned flags;
- for (int s = 0; s< instr->phi.params->size(); s++)
- flags |= itable[(*instr->phi.params)[s]]->flags;
- if (flags & IF_LIVEOUT)
- {
- allocnodeliveout(s,i, mapepi[i]);
- }
- }
- if (itable[mapepi[i]]->flags & IF_LIVEOUT)
- {
- // this one is liveout. Let's do the insertion
- allocnodeliveout(s,i, mapepi[i]);
-
- }
- }
- }
-}
-
void BinInterface::process_branch(const insertion & i, unsigned ** brdest, int scns)
{
unsigned cid = i.idstart;
@@ -822,7 +135,7 @@
unsigned * dest = ibegin + fwd;
// create a branch instruction
- instr = (instruction *)alloca.alloc(sizeof(instruction));
+ instr = (instruction *)alloca->alloc(sizeof(instruction));
instr->flags = flags;
// scan for branch destination
@@ -845,7 +158,7 @@
else
{
// create a generic ALU instruction
- instr = (instruction *)alloca.alloc(sizeof(instruction));
+ instr = (instruction *)alloca->alloc(sizeof(instruction));
instr->flags = flags | IF_ALUOP;
instr->alu.genccf = instr->alu.genrs1 = instr->alu.genrs2 = 0; // zero reg
}
@@ -868,19 +181,20 @@
void BinInterface::complete()
{
+ int p;
assert(sections.size() <= MAX_SECTIONS);
// Compute branch destination table by section
unsigned * brdest[MAX_SECTIONS];
- for (int p = 0; p<sections.size(); p++)
+ for (p = 0; p<sections.size(); p++)
brdest[p] = NULL;
- for (int p = 0; p<queue.size(); p++)
+ for (p = 0; p<queue.size(); p++)
if (!brdest[queue[p].section])
brdest[queue[p].section] = queue[p].begin;
// Complete delayed insertion
- for (int p = 0; p<queue.size(); p++)
+ for (p = 0; p<queue.size(); p++)
process_branch(queue[p], brdest,sections.size());
// Instructions are internalized
@@ -907,9 +221,10 @@
{
printf("l%04d: livein[r%d]\n", instr->self,instr->livein.reg);
}
- else if (instr->flags & IF_NODELIVEOUT)
+ else if (instr->flags & IF_REGSHUFFLE)
{
- printf("r%02d: liveout[l%04d]\n", instr->liveout.reg, instr->liveout.gen);
+ for (int k = 0; k<instr->regshuffle.shuffles->size(); k++)
+ printf("r%02d: liveout[l%04d]\n", (*instr->regshuffle.shuffles)[k].reg, (*instr->regshuffle.shuffles)[k].gen);
}
else if (instr->flags & IF_PHI)
{
@@ -944,7 +259,7 @@
void BinInterface::print()
{
- alloca.print();
+ //alloca->print();
for (int p = 0; p< sections.size(); p++)
{
@@ -984,24 +299,25 @@
// AFTER INSTR AFTER->NEXT
void BinInterface::push_section()
{
- // create header node
- instruction * instr = (instruction *)alloca.alloc(sizeof(instruction));
+ // create header node
+ instruction * instr = (instruction *)alloca->alloc(sizeof(instruction));
instr->next = itable.size();
instr->prev = itable.size();
instr->flags = 0;
instr->self = itable.size();
-
sections.push_back(itable.size());
itable.push_back(instr);
-
}
BinInterface::BinInterface(unsigned instr_count)
- : alloca(BIN_INIT_HEAP_SIZE + instr_count * 16) , itable(&alloca), sections(&alloca),
- queue(&alloca), livein(&alloca)
{
+ alloca = new StackAllocator(BIN_INIT_HEAP_SIZE + instr_count*16);
+ itable.setallocator(alloca);
+ sections.setallocator(alloca);
+ queue.setallocator(alloca);
+ livein.setallocator(alloca);
// create prolog and trace link nodes
push_section();
push_section();
@@ -1010,7 +326,7 @@
unsigned BinInterface::allocnodelivein(int s, int reg)
{
int idx = itable.size();
- instruction * instr = (instruction *)alloca.alloc(sizeof(instruction));
+ instruction * instr = (instruction *)alloca->alloc(sizeof(instruction));
instr->flags = IF_NODELIVEIN;
instr->livein.reg = reg;
instr->self = idx;
@@ -1021,13 +337,12 @@
}
-unsigned BinInterface::allocnodeliveout(int s, int reg, unsigned source)
+unsigned BinInterface::allocnodeshuffles(int s, fvector<shufflepair> * shuffles)
{
int idx = itable.size();
- instruction * instr = (instruction *)alloca.alloc(sizeof(instruction));
- instr->flags = IF_NODELIVEOUT;
- instr->liveout.reg = reg;
- instr->liveout.gen = source;
+ instruction * instr = (instruction *)alloca->alloc(sizeof(instruction));
+ instr->flags = IF_REGSHUFFLE;
+ instr->regshuffle.shuffles = shuffles;
instr->self = idx;
itable.push_back(instr);
@@ -1054,10 +369,12 @@
itable.clear();
sections.clear();
queue.clear();
-
- alloca.clear();
+ livein.clear();
+ alloca->clear();
// create prolog and trace link nodes
push_section();
push_section();
}
+
+
Index: llvm/lib/Reoptimizer/BinInterface/sparcbin.h
diff -u llvm/lib/Reoptimizer/BinInterface/sparcbin.h:1.1 llvm/lib/Reoptimizer/BinInterface/sparcbin.h:1.2
--- llvm/lib/Reoptimizer/BinInterface/sparcbin.h:1.1 Wed Nov 27 20:20:33 2002
+++ llvm/lib/Reoptimizer/BinInterface/sparcbin.h Sat Dec 14 19:32:13 2002
@@ -13,67 +13,25 @@
#include "salloc.h"
#include "fvector.h"
#include "analyze.h"
-
-// Since instructions are dynmically sized union structures
-// *AND* all member types are native integers, I am storing
-// them as arrays of undefined length. Here is a list of
-// valid indices for the various types of instructions.
-//
-//
-
-// flags
-struct instruction
-{
- unsigned next;
- unsigned prev;
- unsigned self;
- unsigned flags;
-
- unsigned instr;
- union
- {
- struct
- {
- unsigned genrs1;
- unsigned genrs2;
- unsigned genccf;
- unsigned genrd; //ingenious SUN.. we can read from RD!?!
- } alu;
- struct
- {
- unsigned dest; // id # of destination section
- } ibranch; // internal branch
- struct
- {
- unsigned * dest;
- } ebranch; // external branch
- struct
- {
- fvector<unsigned> * params;
- }phi;
- struct
- {
- unsigned reg;
- } livein;
- struct
- {
- unsigned reg;
- unsigned gen;
- } liveout;
- };
-};
+#include "sparcpriv.h"
struct vreginfo;
struct regmask;
+struct regmask32;
+struct instruction;
+struct regalloc;
+struct shufflepair;
+static const unsigned SECTION_PROLOG =0;
+static const unsigned SECTION_TRACE =1;
class BinInterface
{
private:
- StackAllocator alloca; // primary stack allocator
+ Allocator *alloca; // primary stack allocator
fvector<instruction *> itable; // maps an unsigned ID
- // to an instruction
+ // to an instruction
fvector<unsigned> sections;
fvector<unsigned> livein; // pointers to all livein nodes
@@ -104,15 +62,15 @@
// returns itable index for new live in node
unsigned allocnodelivein(int s, int reg);
- unsigned allocnodeliveout(int s,int reg, unsigned gen);
-
- void select(fvector<unsigned> &ssa_to_vreg,fvector<vreginfo> &vregs);
+ unsigned allocnodeshuffles(int s, fvector<shufflepair> * shuffles);
+ int spill_load(int vreg, regmask32 & rmask,const int memspills[32], int & freereg, int spills[3], int & spill_cnt, unsigned * & out);
+ void select(regalloc & regs);
- int spillreg(int spillloc, unsigned * & out, fvector<vreginfo> & vregs, regmask & freeregs, unsigned hwregs[32]);
+ int spillreg(int spillloc, unsigned * & out, fvector<vreginfo> & vregs, regmask & freeregs, unsigned hwregs[32]);
- int spill_load(int useid,int id, unsigned * & out, fvector<vreginfo> & vregs, regmask & freeregs, unsigned hwregs[32]);
- unsigned emit_gen(unsigned char * out, fvector<unsigned> &ssa_to_vreg, fvector<vreginfo> & vregs);
+ void prepare_exit(const regalloc & regalloc, fvector<shufflepair> * mod, unsigned * & out);
+ unsigned emit_gen(unsigned char * out, const regalloc & regs);
public:
@@ -121,8 +79,6 @@
// Call newepilog() to get the ID of a new epilog section
unsigned newepilog();
// IDs of prolog and trace sections
- const static unsigned SECTION_PROLOG =0;
- const static unsigned SECTION_TRACE =1;
// initial instruction block insertion. specify section number
// and iterator to machine instructions
@@ -208,4 +164,6 @@
BinInterface(unsigned instr_count);
};
-#endif
\ No newline at end of file
+#endif
+
+
Index: llvm/lib/Reoptimizer/BinInterface/sparcdis.cpp
diff -u llvm/lib/Reoptimizer/BinInterface/sparcdis.cpp:1.4 llvm/lib/Reoptimizer/BinInterface/sparcdis.cpp:1.5
--- llvm/lib/Reoptimizer/BinInterface/sparcdis.cpp:1.4 Wed Nov 27 20:20:37 2002
+++ llvm/lib/Reoptimizer/BinInterface/sparcdis.cpp Sat Dec 14 19:32:14 2002
@@ -22,52 +22,60 @@
#include <stdio.h>
#include <stdlib.h>
-#include "sparc9.hp" // SPARC 9 definitions
+#include "sparc9.h" // SPARC 9 definitions
#include "bitmath.h"
#include <assert.h>
+void sparc_printop_rs1(unsigned instr, int labelrs1)
+{
+ if (labelrs1)
+ printf("l%d", labelrs1);
+ else
+ printf("%s", reg_names[RD_FLD(instr, INSTR_RS1)]);
+}
+
+void sparc_printop_rs2(unsigned instr, int labelrs2)
+{
+ if (labelrs2)
+ printf("l%d", labelrs2);
+ else
+ printf("%s", reg_names[RD_FLD(instr, INSTR_RS2)]);
+}
+
+void sparc_printop_rrd(unsigned instr, int labelrrd)
+{
+ if (labelrrd)
+ printf("l%d", labelrrd);
+ else
+ printf("%s", reg_names[RD_FLD(instr, INSTR_RD)]);
+}
+
void sparc_printbr(unsigned instr, bool labels, int labelrs1, int labelrs2, int labelrd, int labelccf)
{
// look at the OP2 field
if (RD_FLD(instr,INSTR_OP2)==OP2_ILLTRAP)
- printf("ILLTRAP .. ");
+ printf("ILLTRAP");
else if (RD_FLD(instr, INSTR_OP2)==OP2_SETHI)
{
if (RD_FLD(instr, INSTR_RD) == 0)
printf("NOP");
else
{
- if (!labels)
- printf("SETHI %%hi(%08X), r%d", RD_FLD(instr, INSTR_IMM22) << 10, RD_FLD(instr, INSTR_RD));
- else
- printf("SETHI %%hi(%08X), l%d", RD_FLD(instr, INSTR_IMM22) << 10, labelrd);
+ printf("SETHI %%hi(%08X), ", RD_FLD(instr, INSTR_IMM22) << 10);
+ sparc_printop_rrd(instr, labelrd);
}
}
else if (RD_FLD(instr, INSTR_OP2)==OP2_BICC)
{
- printf("%s disp:%08X",icond_names[RD_FLD(instr, INSTR_COND_H)], SIGN_EXTEND(RD_FLD(instr,INSTR_DISP22),22));
+ printf("b%s disp:%08X",icond_names[RD_FLD(instr, INSTR_COND_H)], SIGN_EXTEND(RD_FLD(instr,INSTR_DISP22),22));
}
else if (RD_FLD(instr, INSTR_OP2)==OP2_BPR)
{
//A, RCOND_H, D16HI, P, RS1, D16LO
- if (!labels)
- {
- printf("P%s%s%s r%d, %06X " , rcond_names[RD_FLD(instr, INSTR_RCOND_H)],
- RD_FLD(instr, INSTR_A) ? ",a" : "",
- RD_FLD(instr, INSTR_P) ? ",pt" : ",pn",
- RD_FLD(instr, INSTR_RS1),
- RD_D16(instr)
- );
- }
- else
- {
- printf("P%s%s%s l%d, %06X " , rcond_names[RD_FLD(instr, INSTR_RCOND_H)],
- RD_FLD(instr, INSTR_A) ? ",a" : "",
- RD_FLD(instr, INSTR_P) ? ",pt" : ",pn",
- labelrs1,
- RD_D16(instr)
- );
- }
+ printf("P%s%s%s ", rcond_names[RD_FLD(instr, INSTR_RCOND_H)],
+ RD_FLD(instr, INSTR_A) ? ",a" : "",
+ RD_FLD(instr, INSTR_P) ? ",pt" : ",pn");
+ sparc_printop_rs1(instr, labelrs1);
}
else if (RD_FLD(instr, INSTR_OP2)==OP2_FB)
{
@@ -87,18 +95,21 @@
// OP=OP_2 : RD, OP3, RS1: {I=0 -> RS2 I=1->SIMM13}
if (RD_FLD(instr, INSTR_I)==0)
{
+ printf("%s ", basename);
if (!labels)
- printf("%s r%d <- r%d ,r%d",basename, RD_FLD(instr, INSTR_RD),RD_FLD(instr, INSTR_RS1), RD_FLD(instr, INSTR_RS2));
- else
- printf("%s l%d <- l%d ,l%d",basename, labelrd,labelrs1, labelrs2);
+ printf("%s, ", reg_names[RD_FLD(instr, INSTR_RD)]);
+ sparc_printop_rs1(instr, labelrs1);
+ printf(" ,");
+ sparc_printop_rs2(instr, labelrs2);
}
else
{
+ printf("%s ", basename);
if (!labels)
- printf("%s r%d <- r%d ,%d",basename, RD_FLD(instr, INSTR_RD),RD_FLD(instr, INSTR_RS1), SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)));
- else
- printf("%s l%d <- l%d ,%d",basename, labelrd,labelrs1, SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)));
- }
+ printf("%s, ", reg_names[RD_FLD(instr, INSTR_RD)]);
+ sparc_printop_rs1(instr, labelrs1);
+ printf(" , %d", SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)));
+ }
}
void sparc_printshf(char * basename, unsigned instr, bool labels, int labelrs1, int labelrs2, int labelrd, int labelccf)
@@ -106,17 +117,22 @@
//OP=OP_2: RD, OP_3 RS1: {I=0 -> X & RS2 ,I=1 -> {X=0 -> SHCNT32 X=1->SHCNT64 }}
if (RD_FLD(instr, INSTR_I)==0)
{
+ printf("%s%d ", (RD_FLD(instr, INSTR_X)==0 ? 32 : 64));
if (!labels)
- printf("%s%d r%d <- r%d, by r%d ",(RD_FLD(instr, INSTR_X)==0 ? 32 : 64), basename, RD_FLD(instr, INSTR_RD), RD_FLD(instr, INSTR_RS1), RD_FLD(instr, INSTR_RS2));
- else
- printf("%s%d l%d <- l%d, by l%d ",(RD_FLD(instr, INSTR_X)==0 ? 32 : 64), basename, labelrd, labelrs1, labelrs2);
+ printf("%s, ", reg_names[RD_FLD(instr, INSTR_RD)]);
+
+ sparc_printop_rs1(instr, labelrs1);
+ printf(", ");
+ sparc_printop_rs2(instr, labelrs2);
}
else
{
+ printf("%s%d ", (RD_FLD(instr, INSTR_X)==0 ? 32 : 64));
if (!labels)
- printf("%s%d r%d <- r%d, by 0x%04X ", basename,(RD_FLD(instr, INSTR_X)==0 ? 32 : 64), RD_FLD(instr, INSTR_RD), RD_FLD(instr, INSTR_RS1), (RD_FLD(instr, INSTR_X)==0 ? RD_FLD(instr, INSTR_SHCNT32) : RD_FLD(instr, INSTR_SHCNT64)) );
- else
- printf("%s%d l%d <- l%d, by 0x%04X ", basename,(RD_FLD(instr, INSTR_X)==0 ? 32 : 64), labelrd, labelrs1, (RD_FLD(instr, INSTR_X)==0 ? RD_FLD(instr, INSTR_SHCNT32) : RD_FLD(instr, INSTR_SHCNT64)) );
+ printf("%s, ", reg_names[RD_FLD(instr, INSTR_RD)]);
+
+ sparc_printop_rs1(instr, labelrs1);
+ printf(", 0x%04X", (RD_FLD(instr, INSTR_X)==0 ? RD_FLD(instr, INSTR_SHCNT32) : RD_FLD(instr, INSTR_SHCNT64)));
}
}
@@ -217,16 +233,18 @@
case OP3_MOVcc:
{
- if (RD_FLD(instr, INSTR_I)==0)
- printf("mov%s(%s) r%d <- r%d", icond_names[RD_FLD(instr, INSTR_COND_L)],
- cc_names[(RD_FLD(instr, INSTR_CC2) << 2) | (RD_FLD(instr, INSTR_MOV_CC1) << 1) | RD_FLD(instr, INSTR_MOV_CC0)],
- RD_FLD(instr, INSTR_RD),
- RD_FLD(instr, INSTR_RS2));
+ printf("mov%s(%s) ", icond_names[RD_FLD(instr, INSTR_COND_L)],
+ cc_names[(RD_FLD(instr, INSTR_CC2) << 2) | (RD_FLD(instr, INSTR_MOV_CC1) << 1) | RD_FLD(instr, INSTR_MOV_CC0)]);
+
+ if (!labels)
+ printf("%s, ", reg_names[RD_FLD(instr, INSTR_RD)]);
+
+ if (RD_FLD(instr, INSTR_I)==0) // RS2
+ sparc_printop_rs2(instr, labelrs2);
else
- printf("mov%s(%s) r%d <- %d", icond_names[RD_FLD(instr, INSTR_COND_L)],
- cc_names[(RD_FLD(instr, INSTR_CC2) << 2) | (RD_FLD(instr, INSTR_MOV_CC1) << 1) | RD_FLD(instr, INSTR_MOV_CC0)],
- RD_FLD(instr, INSTR_RD),
- SIGN_EXTEND(RD_FLD(instr, INSTR_SIMM11),11));
+ printf("%d", SIGN_EXTEND(RD_FLD(instr, INSTR_SIMM11), 11));
+
+
return;
}
@@ -365,17 +383,20 @@
case OP3_JMPL: //OP=OP_2 RD, RS1 {I=0-> RS2, I=1->SIMM13}
if (RD_FLD(instr, INSTR_I)==0)
{
- if (!labels)
- printf("JMPL link:r%d, to: r%d+r%d", RD_FLD(instr, INSTR_RD),RD_FLD(instr, INSTR_RS1),RD_FLD(instr, INSTR_RS2) );
- else
- printf("JMPL link:l%d, to: l%d+l%d", labelrd,labelrs1,labelrs2 );
+ printf("jmpl link:");
+ sparc_printop_rrd(instr, labelrd);
+ printf(", to: ");
+ sparc_printop_rs1(instr, labelrs1);
+ printf("+");
+ sparc_printop_rs2(instr, labelrs2);
}
else
{
- if (!labels)
- printf("JMPL link:r%d, to: r%d+%d", RD_FLD(instr, INSTR_RD),RD_FLD(instr, INSTR_RS1),SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)) );
- else
- printf("JMPL link:l%d, to: l%d+%d", labelrd,labelrs1,SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)) );
+ printf("jmpl link:");
+ sparc_printop_rrd(instr, labelrd);
+ printf(", to: ");
+ sparc_printop_rs1(instr, labelrs1);
+ printf("+%d",SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)));
}
return;
@@ -386,52 +407,54 @@
case OP3_RETURN:
if (RD_FLD(instr, INSTR_I) == 0)
{
- if (!labels)
- printf("RETURN r%d + r%d", RD_FLD(instr, INSTR_RS1), RD_FLD(instr, INSTR_RS2));
- else
- printf("RETURN l%d + l%d", labelrs1, labelrs2);
+ printf("return ");
+ sparc_printop_rs1(instr, labelrs1);
+ printf("+");
+ sparc_printop_rs2(instr, labelrs2);
}
else
{
- if (!labels)
- printf("RETURN r%d + %d", RD_FLD(instr, INSTR_RS1), SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)));
- else
- printf("RETURN l%d + %d", labelrs1, SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)));
+ printf("return ");
+ sparc_printop_rs1(instr, labelrs1);
+ printf("+%d",SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)));
}
return;
case OP3_SAVE:
if (RD_FLD(instr, INSTR_I) == 0)
{
- if (!labels)
- printf("save r%d , r%d, r%d", RD_FLD(instr, INSTR_RS1), RD_FLD(instr, INSTR_RS2), RD_FLD(instr, INSTR_RD));
- else
- printf("save l%d , l%d, l%d", labelrs1, labelrs2, labelrd);
- }
+ printf("save ");
+ sparc_printop_rs1(instr, labelrs1);
+ printf(", ");
+ sparc_printop_rs2(instr, labelrs2);
+ printf(", ");
+ sparc_printop_rrd(instr, labelrd);
+ }
else
{
- if (!labels)
- printf("save r%d , %d, r%d", RD_FLD(instr, INSTR_RS1), SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)), RD_FLD(instr, INSTR_RD));
- else
- printf("save l%d , %d, l%d", labelrs1, SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)), labelrd);
+ printf("save ");
+ sparc_printop_rs1(instr, labelrs1);
+ printf(", %d, ", SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)));
+ sparc_printop_rrd(instr, labelrd);
}
return;
case OP3_RESTORE:
if (RD_FLD(instr, INSTR_I) == 0)
{
- if (!labels)
- printf("RESTORE r%d , r%d, r%d", RD_FLD(instr, INSTR_RS1), RD_FLD(instr, INSTR_RS2), RD_FLD(instr, INSTR_RD));
- else
- printf("RESTORE l%d , l%d, l%d", labelrs1, labelrs2, labelrd);
- }
+ printf("restore ");
+ sparc_printop_rs1(instr, labelrs1);
+ printf(", ");
+ sparc_printop_rs2(instr, labelrs2);
+ printf(", ");
+ sparc_printop_rrd(instr, labelrd);
+ }
else
{
- if (!labels)
- printf("RESTORE r%d , %d, r%d", RD_FLD(instr, INSTR_RS1), SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)), RD_FLD(instr, INSTR_RD));
- else
- printf("RESTORE l04%d , %d, l04%d",labelrs1, SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)), labelrd);
-
+ printf("restore ");
+ sparc_printop_rs1(instr, labelrs1);
+ printf(", %d, ", SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)));
+ sparc_printop_rrd(instr, labelrd);
}
return;
@@ -442,21 +465,52 @@
assert(0);
}
-void sparc_printldst(char * basename, unsigned instr, bool labels, int labelrs1, int labelrs2, int labelrd , int labelccf)
+void sparc_printload(char * basename, unsigned instr, bool labels, int labelrs1, int labelrs2, int labelrd , int labelccf)
{
if (RD_FLD(instr, INSTR_I)==0)
{
+ printf("%s ", basename);
if (!labels)
- printf("%s r%d <- r%d , r%d", basename,RD_FLD(instr, INSTR_RD), RD_FLD(instr, INSTR_RS1), RD_FLD(instr, INSTR_RS2));
- else
- printf("%s l04%d <- l%d , l%d", basename, labelrd, labelrs1, labelrs2);
+ {
+ sparc_printop_rrd(instr, labelrd);
+ printf(", ");
+ }
+ sparc_printop_rs1(instr, labelrs1);
+ printf("+");
+ sparc_printop_rs2(instr, labelrs2);
}
else
{
+ printf("%s ", basename);
if (!labels)
- printf("%s r%d <- r%d , %d",basename, RD_FLD(instr, INSTR_RD), RD_FLD(instr, INSTR_RS1), SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)));
- else
- printf("%s l%d <- l%d, l%d", basename, labelrd, labelrs1,SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)));
+ {
+ sparc_printop_rrd(instr, labelrd);
+ printf(", ");
+ }
+ sparc_printop_rs1(instr, labelrs1);
+ printf("+%d", SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)));
+ }
+}
+
+void sparc_printstore(char * basename, unsigned instr, bool labels, int labelrs1, int labelrs2, int labelrd , int labelccf)
+{
+ if (RD_FLD(instr, INSTR_I)==0)
+ {
+ printf("%s ", basename);
+ sparc_printop_rrd(instr, labelrd);
+ printf(", ");
+ sparc_printop_rs1(instr, labelrs1);
+ printf("+");
+ sparc_printop_rs2(instr, labelrs2);
+
+ }
+ else
+ {
+ printf("%s ", basename);
+ sparc_printop_rrd(instr, labelrd);
+ printf(", ");
+ sparc_printop_rs1(instr, labelrs1);
+ printf("+%d", SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)));
}
}
void sparc_print3(unsigned instr, bool labels, int labelrs1, int labelrs2, int labelrd, int labelccf)
@@ -470,51 +524,51 @@
{
//OP=OP_3 RD, Rs1 {I=0->RS2, I=1->SIMM13}
case OP3_LDSTUB:
- sparc_printldst("LDSTUB", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
+ sparc_printload("LDSTUB", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
return;
case OP3_STB:
- sparc_printldst("STB", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
+ sparc_printstore("STB", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
return;
case OP3_STH:
- sparc_printldst("STH", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
+ sparc_printstore("STH", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
return;
case OP3_STW:
- sparc_printldst("STW", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
+ sparc_printstore("STW", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
return;
case OP3_STX:
- sparc_printldst("STX", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
+ sparc_printstore("STX", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
return;
case OP3_LDSB:
- sparc_printldst("LDSB", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
+ sparc_printload("LDSB", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
return;
case OP3_LDSH:
- sparc_printldst("LDSH", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
+ sparc_printload("LDSH", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
return;
case OP3_LDSW:
- sparc_printldst("LDSW", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
+ sparc_printload("LDSW", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
return;
case OP3_LDUB:
- sparc_printldst("LDUB", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
+ sparc_printload("LDUB", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
return;
case OP3_LDUH:
- sparc_printldst("LDUH", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
+ sparc_printload("LDUH", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
return;
case OP3_LDUW:
- sparc_printldst("LDUW", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
+ sparc_printload("LDUW", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
return;
case OP3_LDX:
- sparc_printldst("LDX", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
+ sparc_printload("LDX", instr,labels,labelrs1, labelrs2, labelrd, labelccf);
return;
case OP3_CASA:
@@ -588,3 +642,6 @@
else if (RD_FLD(instr,INSTR_OP)==OP_3)
sparc_print3(instr,false,0, 0, 0, 0 );
}
+
+
+
Index: llvm/lib/Reoptimizer/BinInterface/sparcdis.h
diff -u llvm/lib/Reoptimizer/BinInterface/sparcdis.h:1.3 llvm/lib/Reoptimizer/BinInterface/sparcdis.h:1.4
--- llvm/lib/Reoptimizer/BinInterface/sparcdis.h:1.3 Wed Nov 27 20:20:42 2002
+++ llvm/lib/Reoptimizer/BinInterface/sparcdis.h Sat Dec 14 19:32:18 2002
@@ -18,17 +18,19 @@
//
// 2002 Cameron Buschardt
//*****************************************************************************
-
-#ifndef __SPARCDIS__
-#define __SPARCDIS__
-// Conventional Disassembly. Prints instruction (no newline)
-void sparc_print(unsigned instr);
-
-// Pseudo disasm
-// uses the integers in labelrs1, labelrs2, labelrd, and labelccf as
-// gen labels for the parameter sources
-// instead of printing rxx for rs1, it will print l__labelrs1__
+
+#ifndef __SPARCDIS__
+#define __SPARCDIS__
+// Conventional Disassembly. Prints instruction (no newline)
+void sparc_print(unsigned instr);
+
+// Pseudo disasm
+// uses the integers in labelrs1, labelrs2, labelrd, and labelccf as
+// gen labels for the parameter sources
+// instead of printing rxx for rs1, it will print l__labelrs1__
void sparc_print_pseudo(unsigned instr, int labelrs1, int labelrs2, int labelrd, int labelccf);
-
-
-#endif
\ No newline at end of file
+
+
+#endif
+
+
More information about the llvm-commits
mailing list