Patch title: Release 90 bulk changes
Abstract:
File: /language/schedule/pentium.pli
Key:
    Removed line
    Added line
# Copyright  Hubert Tonneau  hubert.tonneau@pliant.cx
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# version 2 along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

scope "/pliant/"
# scope "/pliant/"
module "/pliant/install/ring2.pli"


function is_pentium -> pentium
  arg CBool pentium
  if processor_name<>"i386"
    return false
  if processor_count>1
    return true
  var Int handle := file_open "/pliant_security/this_computer.pdb" 1
  if handle<>(-1)
    while (file_readline handle (var Str l))
      if (l parse "<pdata path=[dq]/env/hardware/processor/model[dq]>" any:(var Str id) "</pdata>")
        pentium := not (id parse "i" (var Int num) any) or num>=586
        file_close handle
        return
    file_close handle
  if os_api="linux" or os_kernel="Linux"
    var Int handle := file_open "/proc/cpuinfo" 1
    if handle<>(-1)
      pentium := false
      while (file_readline handle (var Str l))
        if (l parse word:"flags" ":" any word:"tsc" any)
          pentium := true
      file_close handle
      return
  # console "  assuming that the processor is pentium class[lf]"
  pentium := true

constant processor_is_pentium is_pentium

export processor_is_pentium


if processor_is_pentium

  function i386_counter eax edx
    arg_w Int eax edx
  function generate_i386_counter i f
    arg_rw Instruction i ; arg_rw Function f
    check i:0:where=argument_register and i:0:register=i386_eax
    check i:1:where=argument_register and i:1:register=i386_edx
    f code_immediat 0Fh 1 ; f code_immediat 31h 1
  (the_function i386_counter Int Int) set_generate_binary (the_function generate_i386_counter Instruction Function)
  ((the_function i386_counter Int Int) arg 0) access := access_write+access_byvalue
  ((the_function i386_counter Int Int) arg 1) access := access_write+access_byvalue
  
  function pentium_counter low high
    arg_w uInt low high
    has_side_effects
    gcc_inline "asm( [dq].byte 0x0f; .byte 0x31[dq] : [dq]=a[dq]($1),[dq]=d[dq]($2) : );"
  function assemble_pentium_counter i gc
    arg_rw Instruction i ; arg_rw GeneratorContext gc
    var Link:Argument eax :> gc register i386_eax
    var Link:Argument edx :> gc register i386_edx
    var Pointer:Instruction cur :> i
    cur :> gc insert_after_instruction cur (instruction (the_function i386_counter Int Int) eax edx)
    cur :> gc insert_after_instruction cur (instruction (the_function i386_mov Int Int) eax i:0)
    cur :> gc insert_after_instruction cur (instruction (the_function i386_mov Int Int) edx i:1)
    gc remove i
  (the_function pentium_counter uInt uInt) set_generate_assembly (the_function assemble_pentium_counter Instruction GeneratorContext)

  export pentium_counter