// UtilDP.bcpl 
// Copyright Xerox Corporation 1979



external [
//the exported procedures
	SetUpDP
	AssignDP
	NegateDP
	DoubleLShift
	DoubleRShift
	DoubleSubtract
	DoubleUsc

//from the OS
	DoubleAdd
	Usc
	CallSwat
	]


external [
	zeroDP;  oneDP;  minusOneDP
	]

static [
	zeroDP;  oneDP;  minusOneDP
	]

let SetUpDP(sixFreeWords) be
	[
	sixFreeWords!0=0;  sixFreeWords!1=0
	zeroDP=sixFreeWords
	sixFreeWords!2=0;  sixFreeWords!3=1
	oneDP=sixFreeWords+2
	sixFreeWords!4=-1;  sixFreeWords!5=-1
	minusOneDP=sixFreeWords+4
	]

and AssignDP(new, old) be
	[
	new!0 = old!0
	new!1 = old!1
	]

and NegateDP(new, old) be
	[
	new!0 = not old!0
	new!1 = not old!1
	DoubleAdd(new, oneDP)
	]

and DoubleSubtract(minuend, subtrahend) be
	[
	let temp = vec 1
	NegateDP(temp, subtrahend)
	DoubleAdd(minuend, temp)
	]

and DoubleLShift(dest, src, amt) be
switchon amt into
	[
  case 0 to 15:
	dest!0 = (src!0 lshift amt)%(src!1 rshift (16-amt))
	dest!1 = src!1 lshift amt
	return
  case 16 to 31:
	dest!0 = src!1 lshift (amt-16)
	dest!1 = 0
	return
  default:
	CallSwat("DoubleLShift called with funny amount.")
	]

and DoubleRShift(dest, src, amt) be
switchon amt into
	[
  case 0 to 15:
	dest!1 = (src!1 rshift amt)%(src!0 lshift (16-amt))
	dest!0 = src!0 rshift amt
	return
  case 16 to 31:
	dest!1 = src!0 rshift (amt-16)
	dest!0 = 0
	return
  default:
	CallSwat("DoubleRShift called with funny amount.")
	]

and DoubleUsc(a, b) = 
selecton Usc(a!0, b!0) into
	[
 case -1:  -1
 case 1:   1
 case 0:   Usc(a!1, b!1)
	]