From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20122 invoked by alias); 8 Apr 2009 02:53:57 -0000 Received: (qmail 20113 invoked by uid 22791); 8 Apr 2009 02:53:55 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_64,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 08 Apr 2009 02:53:46 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n382ri3C013273 for ; Tue, 7 Apr 2009 22:53:44 -0400 Received: from greed.delorie.com (vpn-12-152.rdu.redhat.com [10.11.12.152]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n382rnq5009868 for ; Tue, 7 Apr 2009 22:53:49 -0400 Received: from greed.delorie.com (greed.delorie.com [127.0.0.1] (may be forged)) by greed.delorie.com (8.14.3/8.14.3) with ESMTP id n382rhIp006964; Tue, 7 Apr 2009 22:53:43 -0400 Received: (from dj@localhost) by greed.delorie.com (8.14.3/8.14.3/Submit) id n382rhTc006961; Tue, 7 Apr 2009 22:53:43 -0400 Date: Wed, 08 Apr 2009 02:53:00 -0000 Message-Id: <200904080253.n382rhTc006961@greed.delorie.com> From: DJ Delorie To: sid@sourceware.org Subject: mep C5 support Mailing-List: contact sid-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: sid-owner@sourceware.org X-SW-Source: 2009-q2/txt/msg00001.txt.bz2 This patch adds a couple of things that are needed by the new MeP C5 core: * a write-hint pin for the cache. What this does is mark a cache line "read" without actually reading it, in preparation for the cpu filling the cache line with new data and writing it out. That prevents reading N-1 bytes when you write the first byte of an N-byte cache line. * A variety of new semantics needed by new C5 opcodes. * Support for the C5 core flags. * Regenerated semantics et al (pending http://sourceware.org/ml/cgen/2009-q2/msg00002.html) Ok? * component/cache/cache.cxx (cache_component::cache_component): Add write_hint_pin(). Attach it to write-hint. (cache_component::write_hint): New. * component/cache/cache.h (write_hint_pin): New. (write_hint): New. * component/cgen-cpu/mep/Makefile.am: Regenerate. * component/cgen-cpu/mep/Makefile.in: Regenerate. * component/cgen-cpu/mep/mep-core1-decode.cxx: Regenerate. * component/cgen-cpu/mep/mep-core1-decode.h: Regenerate. * component/cgen-cpu/mep/mep-core1-defs.h: Regenerate. * component/cgen-cpu/mep/mep-core1-model.cxx: Regenerate. * component/cgen-cpu/mep/mep-core1-model.h: Regenerate. * component/cgen-cpu/mep/mep-core1-sem.cxx: Regenerate. * component/cgen-cpu/mep/mep-decode.cxx: Regenerate. * component/cgen-cpu/mep/mep-decode.h: Regenerate. * component/cgen-cpu/mep/mep-defs.h: Regenerate. * component/cgen-cpu/mep/mep-desc.h: Regenerate. * component/cgen-cpu/mep/mep-model.cxx: Regenerate. * component/cgen-cpu/mep/mep-model.h: Regenerate. * component/cgen-cpu/mep/mep-sem.cxx: Regenerate. * component/cgen-cpu/mep/mep.cxx (mep_cpu): Connect write-hint pin. (do_cache): Add C5 support. (do_cache_prefetch): Likewise. (do_casb3, do_cash3, do_casw3): New. * component/cgen-cpu/mep/mep.h: Add C5 support and write-hint pin. (do_casb3, do_cash3, do_casw3): New. * component/families/mep/Makefile.in: Regenerate. * component/families/mep/dsu.in: Add C5 support. * main/dynamic/mainDynamic.cxx: Add C5 support. * main/dynamic/mepCfg.cxx: Connect write-hint pin. * main/dynamic/mepCfg.h: Add C5 support. Index: component/cache/cache.cxx =================================================================== RCS file: /cvs/src/src/sid/component/cache/cache.cxx,v retrieving revision 1.23 diff -p -U3 -r1.23 component/cache/cache.cxx --- component/cache/cache.cxx 5 Feb 2007 20:28:39 -0000 1.23 +++ component/cache/cache.cxx 8 Apr 2009 02:47:11 -0000 @@ -68,6 +68,7 @@ cache_component::cache_component (unsign invalidate_set_pin (this, &cache_component::invalidate_set), flush_and_invalidate_pin (this, &cache_component::flush_and_invalidate_line), prefetch_pin (this, &cache_component::prefetch_line), + write_hint_pin (this, &cache_component::write_hint), lock_pin (this, &cache_component::lock_line), unlock_pin (this, &cache_component::unlock_line), write_allocate_p (false), @@ -101,6 +102,7 @@ cache_component::cache_component (unsign add_pin ("invalidate", &invalidate_pin); add_pin ("flush-and-invalidate", &flush_and_invalidate_pin); add_pin ("prefetch", &prefetch_pin); + add_pin ("write-hint", &write_hint_pin); add_pin ("lock", &lock_pin); add_pin ("unlock", &unlock_pin); add_pin ("operation-status", &operation_status_pin); @@ -355,6 +357,64 @@ cache_component::read_any (host_int_4 ad return st; } +// Prepare a line for writing. This means we are expecting to write +// to all the bytes in the line, so we set it up to *not* read the +// line from the cache on the first write to it, by making the line +// valid if needed. As a side effect, if you don't write to all the +// bytes in the line, unwritten bytes are undefined when written to +// memory. +void +cache_component::write_hint (host_int_4 addr) +{ + bus::status st, read_status; + + if (UNLIKELY (downstream == 0)) + return; + + if (LIKELY (collect_p)) + stats.reads++; + + cache_tag tag = acache.addr_to_tag (addr); + cache_line* line = acache.find (tag); + if (LIKELY (line)) + { + // Line already exists in cache, nothing to do. + } + else + { + // miss! + if (acache.vacancy_p (addr)) + { + if (LIKELY (collect_p)) + stats.replacements++; + + cache_line *expelled_line = acache.expell_line (tag); + assert (expelled_line); + if (expelled_line->valid_p () && expelled_line->dirty_p ()) + { + // flush a dirty line being replaced + if ((st = write_line (*expelled_line)) != bus::ok) + return; + } + expelled_line->set_tag (tag); + // We don't actually read the line, though. + expelled_line->validate (); + } + else + { + // No room in the cache, so our hint must go uneeded. + } + } + + st = bus::ok; + if (line) + st.latency += hit_latency; + else + st.latency = miss_latency; + report_status (st); + return; +} + bus::status cache_component::read_line (cache_line& line) { Index: component/cache/cache.h =================================================================== RCS file: /cvs/src/src/sid/component/cache/cache.h,v retrieving revision 1.11 diff -p -U3 -r1.11 component/cache/cache.h --- component/cache/cache.h 10 May 2005 15:41:05 -0000 1.11 +++ component/cache/cache.h 8 Apr 2009 02:47:11 -0000 @@ -168,6 +168,9 @@ protected: callback_pin prefetch_pin; virtual void prefetch_line (host_int_4 addr); + callback_pin write_hint_pin; + virtual void write_hint (host_int_4 addr); + callback_pin lock_pin; virtual void lock_line (host_int_4 addr); Index: component/cgen-cpu/mep/mep.cxx =================================================================== RCS file: /cvs/src/src/sid/component/cgen-cpu/mep/mep.cxx,v retrieving revision 1.1 diff -p -U3 -r1.1 component/cgen-cpu/mep/mep.cxx --- component/cgen-cpu/mep/mep.cxx 5 Feb 2007 20:28:40 -0000 1.1 +++ component/cgen-cpu/mep/mep.cxx 8 Apr 2009 02:47:13 -0000 @@ -133,6 +133,7 @@ mep_cpu::mep_cpu () add_watchable_pin ("cache-index-invalidate", &cache_index_invalidate_pin); add_watchable_pin ("cache-index-flush-and-invalidate", &cache_index_flush_and_invalidate_pin); add_watchable_pin ("cache-prefetch", &cache_prefetch_pin); + add_watchable_pin ("cache-write-hint", &cache_write_hint_pin); add_watchable_pin ("data-cache-invalidate-all", &data_cache_invalidate_all_pin); add_watchable_pin ("insn-cache-invalidate-all", &insn_cache_invalidate_all_pin); add_watchable_pin ("cache-operation-status", &cache_operation_status_pin); @@ -922,8 +923,16 @@ mep_cpu::do_cache (USI& op, int& rma, PC check_option_dcache (pc); cache_index_flush_and_invalidate_pin.drive (value); break; + case 5: + if (core_type () == CORE_C5) + { + check_option_dcache (pc); + cache_write_hint_pin.drive (value); + } + break; case 6: // address - if (core_type () == CORE_H1) + if (core_type () == CORE_H1 + || core_type () == CORE_C5) { check_option_dcache (pc); cache_invalidate_pin.drive (value); @@ -962,10 +971,11 @@ mep_cpu::do_cache (USI& op, int& rma, PC } VOID -mep_cpu::do_cache_prefetch (USI& op, int& rma, PCADDR& pc) +mep_cpu::do_cache_prefetch (USI& op, int rma, PCADDR& pc) { - // Only implemented on the H1 core. - if (core_type () != CORE_H1) + // Only implemented on the H1 and C5 cores. + if (core_type () != CORE_H1 + && core_type () != CORE_C5) { invalid_insn (pc); return; @@ -1190,6 +1200,58 @@ mep_cpu::do_sleep () sleeping_p = true; } +// C5 Instructions + +VOID +mep_cpu::do_casb3 (SI rl, SI rn, UINT word_addr, UINT pc) +{ + SI temp; + + // Compare and swap byte: + // temp <- Rl + // Rl <- ZeroExt (MemByte (Rm)) + // if (temp == Rl) + // MemByte (Rm) <- Rn [0..7] + // else + // MemByte (Rm) <- Rl [0..7] + + temp = h_gpr_get (rl); + h_gpr_set (rl, ZEXTQISI (GETMEMQI (pc, word_addr))); + + if (temp == h_gpr_get (rl)) + SETMEMQI (pc, word_addr, rn); + else + SETMEMQI (pc, word_addr, rl); +} + +VOID +mep_cpu::do_cash3 (SI rl, SI rn, UINT word_addr, UINT pc) +{ + SI temp; + + temp = h_gpr_get (rl); + h_gpr_set (rl, ZEXTHISI (GETMEMHI (pc, word_addr))); + + if (temp == h_gpr_get (rl)) + SETMEMHI (pc, word_addr, rn); + else + SETMEMHI (pc, word_addr, rl); +} + +VOID +mep_cpu::do_casw3 (SI rl, SI rn, UINT word_addr, UINT pc) +{ + SI temp; + + temp = h_gpr_get (rl); + h_gpr_set (rl, GETMEMSI (pc, word_addr)); + + if (temp == h_gpr_get (rl)) + SETMEMSI (pc, word_addr, rn); + else + SETMEMSI (pc, word_addr, rl); +} + // UCI/DSP pin protocols SI Index: component/cgen-cpu/mep/mep.h =================================================================== RCS file: /cvs/src/src/sid/component/cgen-cpu/mep/mep.h,v retrieving revision 1.2 diff -p -U3 -r1.2 component/cgen-cpu/mep/mep.h --- component/cgen-cpu/mep/mep.h 3 Feb 2009 21:29:28 -0000 1.2 +++ component/cgen-cpu/mep/mep.h 8 Apr 2009 02:47:13 -0000 @@ -166,7 +166,7 @@ namespace mep SI do_ldcb (UINT word_addr); VOID do_stcb (SI rn, UINT word_addr); VOID do_cache (USI& op, int& addr, PCADDR& pc); - VOID do_cache_prefetch (USI& op, int& addr, PCADDR& pc); + VOID do_cache_prefetch (USI& op, int addr, PCADDR& pc); VOID do_smcp (USI rma, DI crn, PCADDR &pc); VOID do_smcpa (UINT rma_ix, SI cdisp8a8, DI crn, PCADDR &pc); @@ -179,6 +179,11 @@ namespace mep VOID do_sleep (); VOID check_write_to_text (UINT address); + // C5 instructions + VOID do_casb3 (SI rl, SI rn, UINT word_addr, UINT pc); + VOID do_cash3 (SI rl, SI rn, UINT word_addr, UINT pc); + VOID do_casw3 (SI rl, SI rn, UINT word_addr, UINT pc); + // Methods for checking if an instruction class is activated. VOID check_option_abs (PCADDR &pc) { check_option (ABS, pc); } VOID check_option_ave (PCADDR &pc) { check_option (AVE, pc); } @@ -247,10 +252,17 @@ namespace mep static const int CORE_C2 = 0x02; static const int CORE_C3 = 0x03; static const int CORE_C4 = 0x04; + static const int CORE_C5 = 0x50; static const int CORE_H1 = 0x10; int core_type () const { return (h_csr_get (17) >> 8) & 0xff; } - int machine () const { return core_type () == CORE_H1 ? bfd_mach_mep_h1 : bfd_mach_mep; } - const char *machine_name () const { return core_type () == CORE_H1 ? "h1" : "mep"; } + int machine () const { switch (core_type ()) { + case CORE_H1 : return bfd_mach_mep_h1; + case CORE_C5 : return bfd_mach_mep_c5; + default: return bfd_mach_mep; } } + const char *machine_name () const { switch (core_type ()) { + case CORE_H1 : return "h1"; + case CORE_C5 : return "c5"; + default: return "mep"; } } private: bool hw_debugger_p; @@ -343,6 +355,7 @@ namespace mep output_pin cache_flush_and_invalidate_pin; output_pin cache_index_flush_and_invalidate_pin; output_pin cache_prefetch_pin; + output_pin cache_write_hint_pin; output_pin data_cache_invalidate_all_pin; output_pin insn_cache_invalidate_all_pin; Index: component/families/mep/dsu.h =================================================================== RCS file: /cvs/src/src/sid/component/families/mep/dsu.h,v retrieving revision 1.1 diff -p -U3 -r1.1 component/families/mep/dsu.h --- component/families/mep/dsu.h 5 Feb 2007 20:28:40 -0000 1.1 +++ component/families/mep/dsu.h 8 Apr 2009 02:47:13 -0000 @@ -24,6 +24,7 @@ using namespace sid; #define MEP_CORE_C2 0x02 #define MEP_CORE_C3 0x03 #define MEP_CORE_C4 0x04 +#define MEP_CORE_C5 0x08 #define MEP_CORE_H1 0x10 class mep_dsu; @@ -133,7 +134,8 @@ private: big_int_4 get_ibc0_te () { return ibc0_te; } void set_ibc0_te (big_int_4 value, big_int_4 mask) { - if (core_type == MEP_CORE_C4 || core_type == MEP_CORE_H1) + if (core_type == MEP_CORE_C4 || core_type == MEP_CORE_H1 + || core_type == MEP_CORE_C5) ibc0_te = value & mask; } @@ -141,7 +143,8 @@ private: big_int_4 get_dbc0_te () { return dbc0_te; } void set_dbc0_te (big_int_4 value, big_int_4 mask) { - if (core_type == MEP_CORE_C4 || core_type == MEP_CORE_H1) + if (core_type == MEP_CORE_C4 || core_type == MEP_CORE_H1 + || core_type == MEP_CORE_C5) dbc0_te = value & mask; } Index: main/dynamic/mainDynamic.cxx =================================================================== RCS file: /cvs/src/src/sid/main/dynamic/mainDynamic.cxx,v retrieving revision 1.13 diff -p -U3 -r1.13 main/dynamic/mainDynamic.cxx --- main/dynamic/mainDynamic.cxx 3 Feb 2009 21:29:29 -0000 1.13 +++ main/dynamic/mainDynamic.cxx 8 Apr 2009 02:47:13 -0000 @@ -51,7 +51,7 @@ static BoardCfg * mk_default (const string name, SessionCfg *sess) { MepBoardCfg *b = new MepBoardCfg (name, "default", sess); - b->set_core_type (MEP_CORE_C4); + b->set_core_type (MEP_CORE_C5); b->set_cpu ("mep-ext1"); b->add_irq_board (); b->set_imem_size (32); Index: main/dynamic/mepCfg.cxx =================================================================== RCS file: /cvs/src/src/sid/main/dynamic/mepCfg.cxx,v retrieving revision 1.4 diff -p -U3 -r1.4 main/dynamic/mepCfg.cxx --- main/dynamic/mepCfg.cxx 3 Feb 2009 21:29:29 -0000 1.4 +++ main/dynamic/mepCfg.cxx 8 Apr 2009 02:47:14 -0000 @@ -910,6 +910,7 @@ public: conn_pin (my_cpu, "cache-flush-and-invalidate", my_cache, "flush-and-invalidate"); conn_pin (my_cpu, "cache-index-flush-and-invalidate", my_cache, "flush-and-invalidate-set"); conn_pin (my_cpu, "cache-prefetch", my_cache, "prefetch"); + conn_pin (my_cpu, "cache-write-hint", my_cache, "write-hint"); conn_pin (my_cpu, "data-cache-invalidate-all", my_cache, "invalidate-all"); if (bit_insn_probe) Index: main/dynamic/mepCfg.h =================================================================== RCS file: /cvs/src/src/sid/main/dynamic/mepCfg.h,v retrieving revision 1.1 diff -p -U3 -r1.1 main/dynamic/mepCfg.h --- main/dynamic/mepCfg.h 5 Feb 2007 20:28:42 -0000 1.1 +++ main/dynamic/mepCfg.h 8 Apr 2009 02:47:14 -0000 @@ -27,6 +27,7 @@ class MepBusArbitratorCfg; #define MEP_CORE_C2 0x02 #define MEP_CORE_C3 0x03 #define MEP_CORE_C4 0x04 +#define MEP_CORE_C5 0x08 #define MEP_CORE_H1 0x10 class MepBoardCfg :