1 (* SYSTEM.mod implement the ISO SYSTEM specification.
3 Copyright (C) 2004-2024 Free Software Foundation, Inc.
4 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 This file is part of GNU Modula-2.
8 GNU Modula-2 is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GNU Modula-2 is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. *)
27 IMPLEMENTATION MODULE SYSTEM
;
29 FROM libc
IMPORT memcpy
, memset
;
32 BitsPerBitset
= MAX(BITSET)+1 ;
36 Max - returns the maximum of a and b.
39 PROCEDURE Max (a
, b
: CARDINAL) : CARDINAL ;
51 Min - returns the minimum of a and b.
54 PROCEDURE Min (a
, b
: CARDINAL) : CARDINAL ;
66 ShiftVal - is a runtime procedure whose job is to implement
67 the SHIFT procedure of ISO SYSTEM. GNU Modula-2 will
68 inline a SHIFT of a single WORD sized set and will only
69 call this routine for larger sets.
72 PROCEDURE ShiftVal (VAR s
, d
: ARRAY OF BITSET;
73 SetSizeInBits
: CARDINAL;
74 ShiftCount
: INTEGER) ;
80 ShiftCount
:= ShiftCount
MOD VAL(INTEGER, SetSizeInBits
) ;
81 ShiftLeft(s
, d
, SetSizeInBits
, ShiftCount
)
84 ShiftCount
:= (-ShiftCount
) MOD VAL(INTEGER, SetSizeInBits
) ;
85 ShiftRight(s
, d
, SetSizeInBits
, ShiftCount
)
87 a
:= memcpy(ADR(d
), ADR(s
), (HIGH(d
)+1)*SIZE(BITSET))
93 ShiftLeft - performs the shift left for a multi word set.
94 This procedure might be called by the back end of
95 GNU Modula-2 depending whether amount is known at compile
99 PROCEDURE ShiftLeft (VAR s
, d
: ARRAY OF BITSET;
100 SetSizeInBits
: CARDINAL;
101 ShiftCount
: CARDINAL) ;
108 IF ShiftCount
MOD BitsPerBitset
=0
110 i
:= ShiftCount
DIV BitsPerBitset
;
112 a
:= memcpy(a
, ADR(s
), (h
-i
)*SIZE(BITSET)) ;
113 a
:= memset(ADR(d
), 0, i
*SIZE(BITSET))
118 lo
:= SHIFT(s
[i
], ShiftCount
MOD BitsPerBitset
) ;
119 hi
:= SHIFT(s
[i
], -(BitsPerBitset
- (ShiftCount
MOD BitsPerBitset
))) ;
121 j
:= i
+ ShiftCount
DIV BitsPerBitset
;
137 ShiftRight - performs the shift left for a multi word set.
138 This procedure might be called by the back end of
139 GNU Modula-2 depending whether amount is known at compile
143 PROCEDURE ShiftRight (VAR s
, d
: ARRAY OF BITSET;
144 SetSizeInBits
: CARDINAL;
145 ShiftCount
: CARDINAL) ;
152 IF ShiftCount
MOD BitsPerBitset
=0
154 i
:= ShiftCount
DIV BitsPerBitset
;
157 a
:= memcpy(ADR(d
), a
, j
* VAL (INTEGER, SIZE (BITSET))) ;
159 a
:= memset(a
, 0, i
* VAL (INTEGER, SIZE (BITSET)))
163 lo
:= SHIFT(s
[i
], BitsPerBitset
- (ShiftCount
MOD BitsPerBitset
)) ;
164 hi
:= SHIFT(s
[i
], -(ShiftCount
MOD BitsPerBitset
)) ;
166 j
:= i
- VAL(INTEGER, ShiftCount
DIV BitsPerBitset
) ;
183 RotateVal - is a runtime procedure whose job is to implement
184 the ROTATE procedure of ISO SYSTEM. GNU Modula-2 will
185 inline a ROTATE of a single WORD (or less)
186 sized set and will only call this routine for larger sets.
189 PROCEDURE RotateVal (VAR s
, d
: ARRAY OF BITSET;
190 SetSizeInBits
: CARDINAL;
191 RotateCount
: INTEGER) ;
197 RotateCount
:= RotateCount
MOD VAL(INTEGER, SetSizeInBits
)
200 RotateCount
:= -VAL(INTEGER, VAL(CARDINAL, -RotateCount
) MOD SetSizeInBits
)
204 RotateLeft(s
, d
, SetSizeInBits
, RotateCount
)
207 RotateRight(s
, d
, SetSizeInBits
, -RotateCount
)
209 (* no rotate required, but we must copy source to dest. *)
210 a
:= memcpy(ADR(d
), ADR(s
), (HIGH(d
)+1)*SIZE(BITSET))
216 RotateLeft - performs the rotate left for a multi word set.
217 This procedure might be called by the back end of
218 GNU Modula-2 depending whether amount is known at compile
222 PROCEDURE RotateLeft (VAR s
, d
: ARRAY OF BITSET;
223 SetSizeInBits
: CARDINAL;
224 RotateCount
: CARDINAL) ;
227 b
, i
, j
, h
: CARDINAL ;
230 (* firstly we set d := {} *)
237 RotateCount
:= RotateCount
MOD SetSizeInBits
;
238 b
:= SetSizeInBits
MOD BitsPerBitset
;
245 lo
:= SHIFT(s
[i
], RotateCount
MOD BitsPerBitset
) ;
246 hi
:= SHIFT(s
[i
], -(b
- (RotateCount
MOD BitsPerBitset
))) ;
247 j
:= ((i
*BitsPerBitset
+ RotateCount
) MOD
248 SetSizeInBits
) DIV BitsPerBitset
;
250 j
:= (((i
+1)*BitsPerBitset
+ RotateCount
) MOD
251 SetSizeInBits
) DIV BitsPerBitset
;
259 RotateRight - performs the rotate right for a multi word set.
260 This procedure might be called by the back end of
261 GNU Modula-2 depending whether amount is known at compile
265 PROCEDURE RotateRight (VAR s
, d
: ARRAY OF BITSET;
266 SetSizeInBits
: CARDINAL;
267 RotateCount
: CARDINAL) ;
269 RotateLeft(s
, d
, SetSizeInBits
, SetSizeInBits
-RotateCount
)